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.



Friday, 9 May 2014

Refactoring configuration

I'm going through an interesting refactoring that I'm doing using roles (my first time) and I'd like to summing up what I'm doing in this blog.

I think that an important feature of Strehler is the possibility to manage custom entities, custom "database tables" that can be manipulated through Strehler backend using all the features Strehler makes available.
New entities can be easly (I hope) added as said in this tutorial, but to give enough freedom to developer, as you can see, there's a lot of flags available in Strehler configuration to change the behaviour of the entity itself.

The actual problem is that not only new custom entities need values for those flags, but also standard entities: Article, Image, User and Log and they can't just use all the default values. Log, for example, is not creatable or editable, it's interface has to be read-only while Article, Image and User allow a complete CRUD flow.
Big question is: where configurations for them are?

Solution until Strehler 1.1.8 is horrible. I've and horrible method (see it here) that fetch informations from config.yml and assign hardcoded values for standard entities.

This solution has, in my opinion, two problems:

  • It's in the wrong place. Six months from now I'll never think that Article configuration is in a curious Strehler::Helper packages package.
  • Makes config.yml the only way to configure entities. Flags are A LOT and many configurations can make this file a real mess.
This is the reason I'm introducing a role consumed by Strehler::Element where every parameter is a method returing, with no input parameters, the value of the flag itself. Standard implementation of every method is just a little piece of code reading from config.yml, as in Strehler::Helper.
Why is this solution better? Because is... more object oriented and allows me (and Strehler developers) to keep informations about entities in the entity class, where they should be. 
So, for example, Article parameters doesn't need no more an external method in a strange place. They're just in Strehler::Element::Article, an override of the standard methods where fetching from config.yml is replaced by returning just the hardcoded value... hardcoded in the right place.

This way, a Strehler developer creating a custom entity can now choose between write down all the configurations in the config.yml or just leave in config.yml minimal configuration needed and add all the parameters in the custom class.
I think that both methods should be used: config.yml when a flag can change through time or in different environments, class methods when a parameter is... "endemic" for the designed entity.

I talked about methods and not attributes because in many cases I need to know class configuration, without an instanced object. Is the same logic of the metaclass_data method.

I hope to release this new configuration soon!

Sunday, 4 May 2014

Messing a lot with files

So we have a 1.1.8 just to bugfix strehler statics. 
Problem using it to update (not create) files on a package update was that file were created all read-only, as they are saved in the CPAN package, and when new ones tried to overwrite them they obtain a permission denied.
Only solution I found is to delete the public/strehler directory from the target project and then copy again it with all the files in the last version. This is not an operation easy to do using perl libraries, I found them a little complicated to use. They don't actually map the shell commands (rm, cp, mv) but follow their logic, so using them for what I needed was a bit difficult.
For example there's not a straight way to copy a directory from a place to another as in:
cp -r $DIR $DESTINATION
If you just use  dircopy from File::Copy::Recursive as:
dircopy($DIR, $DESTINATION)
then all files in $DIR will be trasferred under $DESTINATION (files, NOT the directory).
To obtain what I said you have to... well, copy and paste the magic string:
$File::Copy::Recursive::CPRFComp = 1;
The magic and not-exactly-human-readable string.

I already released a new version because update problem wasn't the only problem of the statics command... Well, the whole command implementation was a mess, with wrong messages and other problems, so i wasn't confortable leaving it in CPAN for a long time. It's just a little number increase...

Friday, 2 May 2014

All the releases come with a bug

So I released Strehler 1.1.7. Now the filter is improved and you can select a category to obtain all the elements in it and in its children.

The real reason I did it, however, is that 1.1.6 has a terrible bug that break the strehler initdb command making impossible a complete Strehler installation as described in the documentation. Strehler installation process is something that MUST go well plain and fast or I judge the entire package useless, because I created it to make a CMS deployment easy.

But... now I found a little problem on strehler statics when it comes to use it to update your statics after an update of the package. Less vital than the solved bug on initdb, but still annoying, probably e new release will be done soon.
At the moment, if you update Strehler package from a version to another (for example from 1.1.6 to 1.1.7) to make all works delete the public/strehler directory in your project and then run strehler statics again. Al the resources will be regenerated in the right version.

Also the Dancer2 0.14000 release gave me some work. As described in the release notes, Runner-Server was untangled. I like the explanation about why this was done, my problem is that all my tests were written using Test::TCP relying on the Dancer2 Standalone Server for the server part. With Dancer2 0.140000 al this part went broken.
So I managed to change this line of code:

Dancer2->runner->server->port($port);
with this if clause

          if( $Dancer2::VERSION < 0.14 )
         {        Dancer2->runner->server->port($port);    }
         else
         {        Dancer2->runner->{'port'} = $port; }

just to keep retrocompatibility.

Thursday, 1 May 2014

Strehler: state of the art

I know that i'm not a frequent writer so a lot of interesting things about me doesn't appear on this place because i'm lazy. So I decided to write just a post to summing up how Strehler is going on after the 1.0.0 release.

Well, a lot of things changed and got better since that day. The first, fundamental step, with 1.1.0 was landing on CPAN with a real test suite and some supporting script. Now you can install Strehler using just cpan -i Strehler and getting an up and running CMS with few commands. In many ways the 1.1.0 release of Strehler is the real first release, because I know that the long, boring and messy installation procedure of 1.0.0 is something NOONE would use, out of me, obviously, but I'm the father of Strehler and my judge is irrilevant.

Strehler 1.1.0 was my first package released on CPAN so I learned a lot releasing it. I learned about PAUSE, about distzilla and about how many thing to your code after you upload it on the perl repository. I did a lot of things wrong because mistakes are the way nature teach you things, so in the week after 1.1.0 release I released FIVE bugfix packeges bringing rapidly Strehler to 1.1.5 version. Well, it's a good thing, high numbers make your software truly professional.

With a quite stable version of my software on the public repository, I started work about little features not yet implemented, like function to order admin list and searchbox. All these things went in the 1.1.6 version and i'm quite proud of it. Yes, a lot of work could be done on the search box because it is implemented in the easiest and plainest way I found, with no indexing or optimizations. It's good because it's accessible just from the backend of your site, but it's probably not a good implementation if you want it also on the frontend.  Probably in the future I'll do something, pluggable if I can, about it.

I'll probably release soon a 1.1.7 version. I wanted to wait after some implementations, but I found a big bug in the strehler script that make impossible to create a strehler database on your custom site, making all the installation process useless. I fixed it and I want to share it with the world as soon as possible.

After that, a lot of adventures are waiting for us!


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.



Friday, 7 March 2014

The clock king

I wrote about timezones telling how avoid problem using them and, in particular, using timestamp fields. As I said in the end of the article the solution has a big flow: it depends on MySQL configuration.

This is not good because best practice is to make your code as system-indepentent as possible. It's good if you can install your sotware without checking MySQL timezone. Because MySQL timezone could be configured by someone who is not you, because you could never know the real MySQL timezone and because YOU'LL NOT CHECK MySQL timezone at installation time. You'll forget it. Don't try to fool me, we both know it will go this way.

So? Is there a better solution? Obviously yes.

Problem is that timestamp field is a field that carry in it timezone information calculating it using its envionment. This property bind it to MySQL timezone and gives us headaches. So, solution is throw timestamp field away and use datetime instead.

Datetime field has no timezone information (basically, it's not converted to UNIX Timestamp when saved on the DB table) so it's just a magic string with a day and an hour. It's less powerful so you can have better control on it. The only thing you have to keep in mind is to ensure that, every time your app write a datetime on the database the timezone it uses is always the same. UTC is usually a good choose.

So, when you insert a new line and you want to trace the moment of insert you no more relay on the MySQL auto-update, but you assign:

timestamp => DateTime->now()

DateTime->now() is already with UTC timezone.

Now you can display your timestamp using any timezone you like. The value you'll receive from database will be UTC so conversion is easy.
Just:

my $ts = $dbix_row->timestamp;
$ts->set_time_zone('UTC') #Remember? Value arrive from  database with floating timezone
$ts->set_time_zone('TIMEZONE_YOU_LIKE') #Starting from UTC the datetime will be converted