Level-2 / Transphporm

Transformation Style Sheets - Revolutionising PHP templating
277 stars 27 forks source link

Validation #34

Open TRPB opened 8 years ago

TRPB commented 8 years ago

@smolinari you mentioned this before and I didn't really get it.. but now I understand what you meant.

I'm thinking of an extra module, that sits on top of transphporm and gives some extra properties. For example:

/* sets validation as required */
input[name="firstname"] { validate: required; validation-error: "You must enter a name"; }

/* matches the value against a regexp */
input[name="email"] {validate: regexp /^.+@.+\.[a-z]{2}[a-z]*$/; validation-error: "You must enter a valid email address"; }

/* calls a PHP function to do validation (e.g. is the email already taken? */
input[name="email"] {validate: call data(obj.someFunction); validation-error: data(); }

/* A generic rule for all inputs to display the error message, using a :invalid pseudo-element */
input:invalid:after {content: error(); }

/* And add a class to the relevant label as long as for="" is set */
label:invalid:attr(class) {content: "error-label"; }

This would then use transphporms internals to parse the sheet and assign the properties. It's then a matter of adding:

$template->validate($_POST);

Which would then set the state of :invalid where needed

smolinari commented 8 years ago

Cool. I said something that got you thinking. LOL! :+1:

I am not sure if that "extra module" should be a needed abstraction. I still think TSSes should allow the direct calling of functions. Go past the lock-in of the CSS standard. :smile: Through the function calls, I should be able to control thing like displaying error messages. That way, I don't need the extra module on top of Transphporm. I just need to know the APIs available to me from the models. Remember, not only does the data logic need to be pulled out of the templates, but also the UI behavior.

I've been thinking too. I've been lurking around some Javascript library/ framework communities and there seems to be real call among them for template rendering to be possible both client- and server-side. I highly doubt there can be a true isomorphic template rendering system, but that isn't really what is needed. Theoretically, TSSes could be the perfect "middle ground" or abstraction to getting to at least some basic to intermediate isomorphic template rendering on both the client and the server. And that is what is needed.

Something else I've noticed, the JS communities seem to be moving more and more to reactive programming. If transphporm could dig into that realm too, from a JS perspective, it would be hitting a huge home run. It is another good reason why I still think TSSes need to be compiled, because there is no way it can be done on the fly and be reactive. The "transphpormation" should be done only once, at the initial call of the system. Depending on client side or server side, the resulting code is JS/HTML or PHTML. In other words, Transphporm would be better and really cool as a transpiler.

Edit: And I know suggesting such a different approach would mean changing a lot of what you have already done. I really wish it didn't.

Scott

TRPB commented 8 years ago

can you tell me what you mean by "reactive"? I don't really follow much javascript development and haven't come across this term before. At a guess I'd say I'd assume it's like setting the .style.display attribute which then re-renders the whole page automatically? This would certainly be possible.

What I was thinking of for the JS implementation is that the update-frequency cache directive, is simply a JS timeout.

div {content: data(foo); update-frequency: 5s}

Which would automatically update the div's content and read from data(foo) every 5s (with possibly some check that it actually has changed for performance reasons)

smolinari commented 8 years ago

can you tell me what you mean by "reactive"?

Just learning this stuff myself. Try this explanation.

https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

It is also the basis for ReactJS from Facebook, which you must have heard something about?

https://facebook.github.io/react/

React can actually do server side rendering too with its ugly JSX. Yuck....! JSX is like the opposite of TSSes to me. It is totally not right at all. LOL!

Scott

TRPB commented 8 years ago

I just read this: http://engineering.silk.co/post/80056130804/reactive-programming-in-javascript

Which is quite interesting, although this is nothing new. This is a MVC model in action... but anyway I can see where you're going with this.

There's no reason TSS can't handle this internally:

div {content: data(foo); }

And then behind the scenes, whenver data is updated the content could be updated. This is actually very easy to implement. The only difference is that you'd need a special wrapper which was part of the TSS library to handle it so instead of:

var output = template.output(data).body;

You'd need

var output = template.output(new Transforn.Reactive(data)).body;

Which would (as far as I can tell with my glance at the topic) be all you'd need and almost trivial to implement using the observer pattern.

Is reactive really just a MVC model? When the model gets updated the change is reflected in the view? Either this idea is certainly not new or I'm missing something fundamental.

TRPB commented 8 years ago

Funnily enough, I already have most of the code for observing changes to JS objects when I was playing around with this: https://github.com/TomBZombie/JSBOM :)

smolinari commented 8 years ago

I have no idea if reactive programming is new or not TBH. I would say the reactive UI isn't really new. It's just being made a lot smarter with the new frameworks and rendering libraries and circling more around asynchronicity. Most of it isn't MVC though, I think. It is MVVM. I've been following a really cool library called VueJS lately. http://vuejs.org/ Cool stuff indeed.

Scott

TRPB commented 8 years ago

Interesting, I can easily make the javascript implementation reactive without much effort. I'll give it a quick go as a proof of concept.

smolinari commented 8 years ago

We sort of got off topic.

If you had a look at Vue, what I think would be cool is TSSes extrapolating the vue api. In other words, you'd have frontend JS devs, who would be creating the behavior in JS and extending the viewmodel and view APIs. You'd have back end developers offering the real "data" and extending the model API. And you'd have designers doing the design with HTML/CSS and using TSSes to meld the data/ behavior and the design together. How cool would that be?

Scott

TRPB commented 8 years ago

Indeed we did, but it was still a good idea! Check this out: https://github.com/Level-2/Tranjsform/blob/master/tests/reactive.html Reactive data :)

edit: And it doesn't rely on timeouts/polling to check for changes to the data object :)

smolinari commented 8 years ago

Nice and I actually get it. Now to build it out to work for full scale applications!

Scott

Pixelfck commented 8 years ago

I think Transphporm should not do validation, or at least, it core of the library should not. Validation is a whole different realm of functionality.

Giving feedback about the results of validation (or any other response in reaction to handling user data) is either is part of the HTML page's logic (typically handled using javascript) or part of the back-end's logic (some component of whichever architectural pattern) or a combination of the two.

Transphporm is great for being able to separate the template logic into a separate .tss file. I think it should stick to this single responsibility: if you start implementing the option to make function calls, it moves into the direction of a new scripting language, which, I think, should be outside the scope of a Template abstraction engine.

If you do want this kind of functionality, I would suggest defining a plug-in system instead and delegate the functionality as proposed in this issue to a plug-in.

smolinari commented 8 years ago

The core system should only need to be able to "bind" the validation functionality. If that is what you mean by "plug-in", then I agree.

As I see it, There are 4 things a "complete" view system needs to accomplish.

Validation, to me, goes under behavior. And granted, validation must be done in the backend too. But, behavior is a necessary part of any (modern and complete) view. The question is, as you say, is behavior a responsibility TSSes should cover?

Scott

cxj commented 8 years ago

Scott: For a simple validation behavior, would an onblur Javascript call to ensure a field contains only digits meet your definition? If so, then what exactly is the binding, and how should TSS accommodate it? I ask because I would like to see Transphporm stay true to its original intent and avoid becoming cluttered with undesirable knowledge, if possible. Perhaps I agree with you, but I'm not sure until I fully understand what you are suggesting.

smolinari commented 8 years ago

Not quite. It would also be the warning to the user that the field is improperly filled out. The binding is between the field, the validation check and the warning output. The warning is a form of data/ state, which needs to be bound to the view too.

Scott

Pixelfck commented 8 years ago

@smolinari, It is true that a view system need to do those things. However, I was under the impression that Transphporm is aiming to be a templating system.

smolinari commented 8 years ago

Yes, and with a templating system, we should be getting something that is supposed to deliver "finished" web pages. And I believe any finished web page today requires all 4 points above. If a templating system only offers 3 of the 4, then we have to get (overly) creative to get the last one. Today, to really stand out from the rest, I feel a template system, a view system for web applications, has to deliver all 4.

Scott

Pixelfck commented 8 years ago

I do not agree with your observations. Transphporm is all about moving the template logic outside the presentation logic. Validation is a form of domain logic, which has nothing to do with the first two. (Client side) validation would require some sort javascript functionality. So, if you would add validation functionality to Transphporm, you would introduce the need for Transphporm delivered javascript. Binding javascript event handlers to html elements can be done from javascript, the time of in-line event handler attributes are, fortunately, long gone.

Also: https://r.je/views-are-not-templates.html

smolinari commented 8 years ago

The rules for validation come from the domain. Yes, this is correct. The behavior of the view to enforce validation is still part of the view and yes, needs to be done with JS, IF the validation should take place on the client (and in this day and age, it should). So, as long as Transphporm stays a pure server-side technology, I actually agree with you. But, in this day and age, pure server-side rendering is totally outdated. If Transphporm sticks to that paradigm, it will never gain any kind of acceptance.

So, I am back to my point. If Transphporm is going to win any hearts, it must include, structure, design, data AND behavior.

The other direction of the argument is, what is the use of extrapolating the data binding out of a template, when you have to go back and use JS to include the behavior, which also needs a lot of the extrapolated data in the TSS, because the state of the applicaion comes from the domain? What a mess.

I've come to the conclusion that Transphporm will never be what I expect of it. It is a great idea. It just isn't the complete win-win-win a true view system needs. And yes, I know. It wasn't meant to be a view system. That is also why it will never take off.

Scott

TRPB commented 8 years ago

This argument is why I'd suggested making validation a separate module that could be loaded if wanted :) This allows the feature to exist for those who want it.

That said, whether or not you have validation done by the view layer, you still need some logic that says "If what's entered into the field doesn't match this pattern, display an error", This is display logic really.

smolinari commented 8 years ago

This is display logic really.

Exactly.

Scott

Pixelfck commented 8 years ago

This is display logic really.

Exactly.

I also recognize that there is an overlap between the concerns. However, in my mind, it clashes with the responsibilities of Transphporm, because Transphporm is a Template animation engine: it works on xml files by applying rules defined in tss files. I don't think introducing javascript into this mix would be the best idea: I believe in specialized libraries; do one job only and provide the best possible solution for said job.

TomBZombie: This argument is why I'd suggested making validation a separate module that could be loaded if wanted :) This allows the feature to exist for those who want it.

It seems we are mostly thinking in the same direction.

Pixelfck: If you do want this kind of functionality, I would suggest defining a plug-in system instead and delegate the functionality as proposed in this issue to a plug-in.

Added bonus: a plugin architecture should keep everybody happy.

Ultimately, I think what you are building here @TomBZombie, has a lot of potential. It could be split out in several sub-projects: tss syntax definitions, parsing tss into an abstract syntax tree, apply the AST on the XML, etc. It would allow for yet another project building a complete view/templating system on top of Transphporm (spontaneous thought: maybe the plugin functionality should included as part of this system?)

TRPB commented 8 years ago

Take a look at the structure of the code. I haven't had a chance to document this but you can add to the current featureset ( https://github.com/Level-2/Transphporm/blob/master/src/FeatureSet.php ) by registering properties, pseudo elements and formatters then assign it to the builder object which is how it works. The default modules are available here: https://github.com/Level-2/Transphporm/tree/master/src/Module which register the basic formatters, properties and pseudo elements.

You can then call $builder->loadmodule($module) to extend the featureset.

cxj commented 8 years ago

Scott wrote:

But, in this day and age, pure server-side rendering is totally outdated. If Transphporm sticks to that paradigm, it will never gain any kind of acceptance.

So, I am back to my point. If Transphporm is going to win any hearts, it must include, structure, design, data AND behavior.

I have to respectfully disagree. Perhaps it won't win Scott's heart, but the entire reason I'm attracted to Trasnphporm is because unlike every other template engine out there, it actually does cleanly separate the display and logic concerns.

Similarly, Scott believes that server-side rendering is totally outdated, but my development team is building an entirely new suite of responsive web application doing just that.

Not every one (in fact, hardly any) of my customers have a high-end device with a processor powerful enough and network connection fast enough to handle piles of Javascript which is then going to completely revise my DOM dozens of times per interaction. That kind of stuff may be the shiznit among some groups of programmers, but it's not necessarily how everyone gets their work done.

So let's stick to design questions, not marketing questions, and try to find some amicable ways to cooperate and if necessary, compromise. Tom's done huge amount of really brilliant, well-designed work here. I greatly appreciate it.

smolinari commented 8 years ago

Not every one (in fact, hardly any) of my customers have a high-end device with a processor powerful enough and network connection fast enough to handle piles of Javascript which is then going to completely revise my DOM dozens of times per interaction.

Practically every device sold today, even the lowest end ones, can handle any decent size JS application and perform well (if the app is designed well). The only issue that these devices have at most would be with bandwidth, and usually this issue isn't coming from the amount of JS loaded, but rather from the calls to the server and the amount of data transferred.

The future of web applications also isn't responsive design. It is progressive enhancement. Why? Because there will be a whole lot more mobile devices out there than PCs. Actually, there are already. So making an ecosystem tailored for them, then adding more to the app for the rest of the devices, allows for a much better development platform. It simplifies the logic and the workflow and gives the users of all devices the best possible UX, which is obviously the ultimate goal.

Also, making the final clear separation between the view layer and the model (and controller) is the last great challenge. More and more backends are becoming API driven. The internet is becoming a landscape of APIs. And having the view strictly in the browser and the model on (the) server(s) is the cleanest way possible to separate them and keeping them as simple as possible. The only thing holding this back is SEO and even then, the spiders are being taught to use JS. Still, people are talking about Isomorphic applications. I think that is the current hype and a dream.

So, one can stick to the old ways or go with the flow. And the flow is going the way it is, not because of trends or shiznittery, but because it makes economic sense. If you are doing something new, you need to look past today and even the near tomorrow. You have to look quite far ahead. And personally, I just don't see server-side rendering being a part of the distant future.

Now, let's also be perfectly clear. Nothing I am saying here is meant to belittle Tom's efforts. I also think they are fantastic and if you've looked at the threads in the past, I've offered a lot of discussion and my feedback to him. Probably more than anyone else. I respect Tom an awful lot. He's one of the best PHP programmers I know.

If Transphporm is what you are looking for and it can help you. Fantastic! I hope it helps your endeavors in all ways you imagined it would and I do wish you the best of fortune with whatever you do with it and otherwise.

Scott

solleer commented 8 years ago

I am beginning to work on a validation module for transphporm and can't figure out how to structure good tests to independently test each property and the invalid pseudo