Showing posts with label HTML::FormFu. Show all posts
Showing posts with label HTML::FormFu. Show all posts

Sunday, 18 May 2014

HTML::FormFu Beastmaster

I'm not a great fan of HTML::FormFu package.
Let me explain: HTML..FormFu does a lot of dirty job and give you an easy way to write down forms with a lot of business logic, but when you try to open is source code to do some customization it's quite a labyrinth with too much trolls and few indications about the right road.
In my opinion the module could be ten times more powerful giving an easy way to hack elements and modify them for new purposes.

Writing down Strehler interface I obviously had to manage a lot of forms. I wrote many of them following Strehler business logic to offer easy ways for javascript to work with them, this logic is something built on top on HTML::FormFu elements.

The category selector, probably the most complex widget I had to use, in forms configuration files is something like this:

    - type: Select
      id: category_selector
      name: category
      label: Category
      constraints:
        type: Required
        message: 'Category needed'
    - type: Select
      name: subcategory
      label: Sub-category
      id: subcat
Problem is that Strehler should give other developers the opportunity to implement their own entities and forms managing them. These forms could contain my category selector and I can't ask people to copy and paste all this code in their YML files. It's really clumsy and what if I change this structure? I should call them one by one and ask to change their files.

TIdy implementation wants that, when you need a category selector, you just add in your form configuration:

- type: "+Strehler::FormFu::Element::Category"

An ad hoc HTML::FormFu element.

There's not a real path to implement something like that, best way I found is to hack a HTML::FormFu::Element::Block nailing in it a fixed configuration with the elements of my category selector. The result is here.

You can do a lot of thngs exploiting the after BUILD of the HTML::FormFu::Element sub-classes, but you'll be always limited to the possibilities given by the class and its methods and, for example, you'll not have any chance to add custom configuration entries. So this pattern can be useful when you just want to make a package of some existing configurations, but nothing more.

Strehler::FormFu::Element::EntitySelect is something a bit more smart, as you can see here, but it's still an hack on Select I did after giving up on creating a FormFu::Element completely by myself.

Working on that, I drew a class diagram of HTML::FormFu (still 0.9 version), doing a bit of reverse engeneering on it. Here it is, as a gift from me.



Saturday, 29 March 2014

The spring of HTML::FormFu

HTML::FormFu arrived on his first major release (1.00) this christmas. It's quite an event considering that previews release was on 05 Oct 2012.

I'm very happy for that because now form rendering is better and cleaner. Problem is that this new rendering had some incompatibility with my Strehler forms (javascript and CSS) so, when I upgraded, thing went a little messed up.

The most interesting thing (the only worth to be written here) is about my little CategoryUnique validator.

Strehler backend manage a category tree that you can use to organize contents. For example:

foo
foo/bar
foo/ber
yetanothercategory
newcategory
newcategory/newson

When you create a new category you have to give its name and its parent. The CategoryUnique validator check if the category already exists under that parent.

In the example up there you can create bar under newcategory, you can't under foo, because there's already one category named that way.

So the validator can't just check about the value of the category field, but it has also  to consider the second parameter of the form, to check if the category has the same name under the same parent.

With HTML::FormFu 0.09010 it was easy:

my $self = shift;
my $parent = $self->form->param_value('partent');

Easy, yes, but apparently forbidden by documentation.
If the value is invalid or the form was not submitted, it returns undef.
In a validator a value cannot be already valid :-)

But it worked because there was a bug, a bug fixed in the December 2012.

We could exploit it just because no new release of HTML::FormFu come after that fix... until December 2013.

What can we do now, with the shiny fixed 1.00 version of the software? The only way I find to do the same thing is to use the undocumented HTML::FormFu::FakeQuery. The query method of the form, infact, doesn't return an hash as documentation still say, but an instance of this object.

Luckly, using it is easy enough:

my $self = shift;

my $query = $self->form->query();
my $parent = $query->param('parent');


without passing through the param method of the form, that HTLM::FormFu documentation itself doesn't trust.



Monday, 22 July 2013

The dumb code festival - 3

In the first two chapters of our dump code festival we just did a lot of frontend developement, something completely independent from the framework we are using and with no server-side logic.
Well, today frontend developement is very important and HTML::FormFu is a very complex and obscure thing so I think it's not so bad we spent all this time on it.

You know? I'm trying to make HTML::FormFu "cooperate" with Twitter Bootstrap. Yes, it's possible and easy enough, but you have to do tricks and you'll never have all the freedom you probably want. However, letting twitter bootstrap render the form make it nicer than not doing it, so... give it a try.

But now we have to talk about logic.
Business logic in a login form is triggered just on submit, when data start its voyage to the server and the server is committed to give an answer to the user. It's like going to the oracle. Yes, the oracle with eyes turned up to the sky and funny clothes, not the oracle database server.

Easiest and probably most elegant way to manage a login form is making is action calling again the login page. This is the meaning of the any keyword we used last time to define the route. You arrive on the login route with a GET (obtaining the form), you process the submitted data with a POST on the same route.

The four needed steps are:

  1. Create the form object
  2. obtain the DATA inserted from the user
  3. process the data
  4. Do something with the data (yes, you can throw it away and laugh, but this way you'll never become a professional programmer)

As you can see the code is very simple and it's just HTML::FormFu syntax mixed up with very few Dancer2 magic.
We saw the first two lines in the last chapter. They, with the last one, make the form appear on the screen. The params keyword retriver all the variables arrived with the request, it's a pointer to an hash that's suitable for the $form->process. Process takes every key in the hash and put it in the field of the form with the same name, triggering contraints, validators, inflators etc. etc. The result of this computation is in the submitted_and_valid variable that can be easly tested to see if the data can be processed.

Staying in the same route makes all the messages easy to manage. The process can find a violeted contraint, for example (as an empty field, as we configured), then it can write the error message directly in the form and the rendering, on the bottom of the route, will make it automatically visible.

In the GET scenario no param is present, process receive an undef and do nothing to change the form. The render will display the form untouched, ready to be used.

What about the login_valid? It's up to you, you have to decide when a user is good and when it's not.
This is a easy and dumb implementation:



Users and passwords are on a little DB table, accessible using the Dancer2::Plugin::DBIC (as always). Remember: just the MD5 for your password IS NOT a secure way to store it. But, as I said, this is just an example.

Well, there's just one more thing to say, probably the most interesting because it's the one about Dancer2 structure and server-side logic. It's just this: now we have a login page, what we need is that it appears every time someone try to navigate our admin panel. EVERY TIME.

Sunday, 14 July 2013

The dumb code festival - 2

Let us spend some more words about forms and HTML::FormFu. In the preview chapter we just scratched the surface of it, doing something too essential to be enough, even in a dumb code festival.

Form is a way to have a structured stream of input coming from a human being to a machine. Human beings are bad doing data input. They insert bad data, they're lazy, they use funny mysterious languages like english and they're often stupid. You can't trust them, you have to constraint them, filter their input, inflate it and validate. (you would also bring them all and in the darkness bind them but this is not a tutorial suited for that).

Keeping us near the little example we're working on, a login, box, what kind of bad input we should manage? Luckly, very little, the only bad thing a user could try is to submit the form with no data inside. We could ignore this case, obviously it will led to a bad login, but let us make HTML::FormFu manage it for us.

Very little code added, just a contraints field with an element. The element is defined by a type and a message to me thrown up when constraint is violeted.

An interesting thing about: where that "Requeired" word come from? How can I know which words can do this kind of magic? Is there a sort of grimorioum for them?
Obviously not, the keyword you put in the type is just the name of a perl package, in the HTML::FormFu::Constraint namespace. The one invoked here is this.
What does this mean? It means that you can look at the available constraints just surfing the CPAN for contrainst classes and that you can use constraints created by your own just giving them the HTML::FormFu::Constraint namespace and putting them in the configuration file as "official" ones.
And yes, filters, inflaters and validators follow the same logic!

Just updating the form configuration you have managed the empty fields case. HTML::FormFu will reject the submission and will display errors on screen if the user try to submit without writing anything (lazy, lazy human!).

Now two important downsides:

  1. Validation is server-side. The form is submitted, POST data elaborated, page reloaded with errors. If you're aiming to a validation with no page refresh and client-side javascript magic you're looking in the wrong place.
  2. HTML produced by FormFu is the HTML it likes. You could not like it. You could think is a little old-style, too rude and simple. For example, I hate it doesn't use the Label for attribute.
    You can decide to work "around it" knowing how it is and putting javascript and CSS to make it looks good. The harder way is going down in the HTML::FormFu classes and redefine the rendering. This thing is not enough dumb for this article.
But... probably after so many words you want to see your form, don't you?
Open your Dancer App and render it!


The any key to acquire GET and POST will come useful in the future. Remember that the login.yml will be searched in you app root, the same directory where the Dancer config.yml is placed. Subdirectories are allowed (and recommended).
Remember to have in your template a [% form %] token where the box will be displayed.

This piece of code is very stupid, nearly useless, because there's no logic. But it's just the second part and we have a lot of things to talk about.

Saturday, 13 July 2013

The dumb code festival - 1

One thing I usually miss when I google things about Dancer2 (or other coding stuff) is examples of simple working code doing normal things. Every time you find just little snippets that do just a thing in a way that will be useless to you ore code doing wonderful, exciting things you don't need.
For Dancer2 we have this article from Sukrieh himself that is very useful to learn how Dancer2 works, but... just this.

I want to put in this blog all the things I don't find in internet so I decided to start some articles about an obvious, stupid thing you all do blind and tied up while singing Yellow Submarine. Just because I think that out there there's someone who's not singing loud enough.

Let's talk about a little adminitration panel for your website. I'm not interestend in what your website do, there're a lot of things an administration panel has to do anyway. The most important thing is that it has to keep out all the non-authorized people and let the authorized in.

Authorized people will enter somewhere username and password. There're a lot of ways to do this (and some plugin from Dancer that could be easly migrated to Dancer2) but we'll to it from scratch in the most obvious way: a login page.

A login page is just a form with you fields, a big red button and a lot of threatening messages when you do wrong things.

Talking about forms, perl and frameworks, you should learn about HTML::FormFu, one of the most used libraries for forms in perl.
Using it, you'll translate all the logic you want in the form in a configuration file, adding to it, eventually, some libraries for validation, filtering and so on, downloaded from CPAN or written by you.
You could think this is too much complex and without real gain for your coding, especially when you are dealing with little forms.
My advice is to always follow this design path for two important reasons:

  1. If you don't use it with simple problems, you'll NEVER use it in complex one. Don't lie.
  2. In every case templating the form is keep separated from coding is logic, something you must do if you want to write tidy code.
A login box using HTML::FormFu at his minimum potential has a config file (login.yml) like this:


You can make it a little more beautiful, but all the logic you need is here.

For this time we'll stop here, i wrote the introduction to this experiment, so the article is already long enough. Numbers near the title means that we'll go on. I hope that I'll create something useful with this, useful for the internet and also for me, to make my mind a little more clear about what I do.