jeudi 21 juin 2007

Améliorer les objets

En fouillant pour voir l'utilisation d'object.extend dans Scriptaculous, je suis tombé sur cet article:

http://www.bloglines.com/blog/reinyannyan?id=1

Ça me parait une excellente idée d'implémenter ça, en reprenant même directement son code, puisque celui-ci le permet :)

Ceci permet de faire facilement:
  • des classes abstraites
  • des classes concrètes
  • de l'héritage
  • de pouvoir appeler le constructeur du parent
  • de pouvoir instancier des singletons
  • de pouvoir rajouter des méthodes à un objet
  • de pouvoir rajouter des méthodes de type singleton dans des classes multi instanciées
Bref un excellent boulot de la part de M. inconnu qui ne veut pas dire son nom :)

Merci M. inconnu !

mardi 19 juin 2007

Ca bouge !

Voilà quelques jours que nous n'avons rien dit ici ... Mais ça bouge beaucoup sous le capot d'Archetype.

Par contre, on ne respecte pas du tout les ToDo pour le moment ... !

Alors, tout d'abord, Swiip nous a fait un magnifique moteur de template "à la smarty", il est très bien et pas gourmand en ressource :)

Sinon on a trouvé un moteur javascript de template, reprenant la syntaxe de TAL ( le, à mon humble avis, superbe système de template de Zope), utilisant le DOM pour aller vite et se simplifier la vie... Mais celui-ci requiert que le template soit directement inséré dans le dom pour créer le html, ce qui me gène un peu. Il faudrait insérer le template dans une balise html cachée pour interprétation avant de la copier dans le html visible pour qu'elle soit satisfaisante, ce qui ne me parait pas super propre :/

Ce moteur est testable ici : http://www.heute-morgen.de/test/domtal.html regardez le fichier javascript si vous êtes curieux de voir comment ça marche :) Un merci a Joachim Zobel d'avoir créé cette petite librairie, je pense que nous le contacterons en temps voulu si on trouve une manière adéquate d'intégrer son code pour un moteur de template en TAL :)

Les templates montrant le bout de leur nez, nous avons naturellement commencé à regarder comment les inclure élégamment dans le code.

Swiip est encore en train de faire des modifications sur le require pour gérer au mieux les inclusions d'inclusion d'inclusion ... etc.

Pour ma part, je mets les mains dans le cambouis aussi sur une des fonctionnalités les plus importantes d'Archetype: les composants (peut-être s'appeleront-ils archetypes dans un futur où ils seront achevés de penser/coder).

Qu'est-ce qu'un composant ? C'est un outil pour faire du M.V.C. (Modèle Vue Contrôleur).

Rien de pire que de mélanger le code et la structure dans une application. Grâce aux templates, nous pouvons gérer une vue, que le contrôleur chargera quand on l'instancie. La vue peut représenter une page entière, un bout de page, et si l'application est correctement découpeé, la vue ne contient jamais grand chose sinon des inclusions d'autres vue/contrôleur (ici c'est l'inclusion d'un composant).

Ceci parait bien compliqué à instancier et pourrait s'avérer lourd à utiliser. Mais on code un framework, notre but est donc de faciliter la vie du programmeur et de lui offrir de nouvelles possibilités :)

Dans Archetype, un composant est donc un fichier JS décrivant les dépendances qui lui sont nécessaires, et une fonction "main()" appelée lorsque le composant a toutes ses dépendances à disposition.

Mais on ne s'arrête pas là. Archetype créé un composant à partir de cette description. Comme c'est lui qui a la main et qui construit l'objet il peut facilement rajouter des services et des méthodes à l'objet constituant le contrôleur du composant.

Aussi, en se basant simplement sur l'objet décrit, on va pouvoir lui rajouter, grâce aux noms des fonctions le composant, des services utiles, divers et variés:
  • On pourra changer le logger par composant (via configuration, façon Log4J).
  • On pourra faire de l'inversion de contrôle (via configuration, comme Spring)
  • On pourra préfixer, composant par composant, méthode par méthode et automatiquement, la sortie du logger, pour facilement savoir où se trouve un problème.
  • Toutes les fonctions commençant par "on" réagiront a l'évènement décrit par le nom, suivant la syntaxe :"on"+nom de l'évènement (exemple: "onShoppingCartAddProduct") et seront automatiquement "bindé" comme event Listener(en utilisant dans la construction de la fonction, le fameux bindAsEventListener), permettant d'utiliser "this" dedans sans le décrire explicitement.
  • Toutes les fonctions commençant par "send" seront enregistrées dans "Archetype.Events" comme fournisseuse d'évènements. On pourra même utiliser une fonction vide si la fonction ne fait qu'envoyer l'évènement en lui passant les paramètres de la fonction. Par exemple, pour le composant ShoppingCart, on pourra créer la fonction:
    sendAddProduct: Prototype.emptyFunction(productId,quantity)
  • avant ou après chaque appel à une méthode, on pourra configurer l'appel de fonction, basé sur une configuration (logger, gestion du mode offline de manière transversale, etc.)
Bref, les composants sont une sorte de Tapestry/Struts + un Spring éventuellement :)

Donc voilà, de gros gros développement en cours en ce moment, de quoi donner un vrai coeur a Archetype :)

mardi 12 juin 2007

Template JS !

Voilà qui est lancé, un premier jet du moteur de template est parti.

Cela sera inévitablement une des bases d'un système Web côté client. Après des années de jsp, de php, de smarty et j'en passe, il est peu concevable de faire du Web en collant des bouts de code HTML dans des chaînes de caractères JavaScript. Tous les langages que je connais ont une syntaxe plus ou moins approfondie de template HTML. Hé bien, cela le sera aussi en JavaScript.

Nous avons trouvé un ou deux moteurs déjà implémentés en JavaScript même si c'est un concept auquel peu de gens semblent s'intéresser. Mais on ne peut pas dire que leur code source soit limpide et nous aimerions quelque chose que nous puissions faire évoluer à notre gré.

Nous avons choisis de partir sur les bases de l'objet Template de Prototype, cela a l'avantage de nous donner la possibilité de proposer l'évolution à Prototype directement quand elle sera ok.

Pour finir, le système de prototype se base sur des regexp (m'enfin sûrement tous les moteurs le font mais bon...), j'espère qu'il sera possible à terme de pouvoir proposer le même moteur avec différentes syntaxes de template pour arranger ceux qui ont leurs habitudes avec certains langages de templates.

En tout cas, on a déjà les bases d'une boucle et d'une condition, il va être possible d'avancer rapidement de ce coté.

Mon but est maintenant de peaufiner mes deux bébés à savoir le require et les Templates qui seront la base de la structure de Composant dont les contours se dessinent de plus en plus précisément.

dimanche 10 juin 2007

Un logger ?

Tous les adeptes de Firebug connaissent un de ses principaux intérêts : le Logger (console.log), permettant de programmer sans mettre des "alert" de partout dans le code !

Aussi j'avais dans la volonté qu'Archetype gère différentes façons de logger facilement (changer dans 10 fichiers d'en-tête firebug pour firebugx n'est pas pratique à mon avis, même si en théorie on n'a jamais tant d'en tête... sauf pour un site avec des mises en page très différentes).

A noter que prototype window fournit aussi un système de log, ça pourrait être sympa à intégrer comme logger, idem pour le logger d'event des custom Events.

Donc voilà, le Logger est instancié au début de l'application, utilisant la classe indiquée dans la configuration. Ça marche très bien avec le logger 'Null' et le 'Firebug'

J'aimerai atteindre un niveau de configuration permettant de travailler comme avec Log4J. J'ai eu quelques idées là-dessus il y a quelques semaines mais j'avoue qu'elles m'ont échappées depuis, si vous avez une bonne idée, je suis preneur (si possible, quelque chose de non intrusif au niveau du code...)

samedi 9 juin 2007

Implémentation du concept de page

Comment lancer le main() de notre programme utilisant Archetype ?

Actuellement on n'avait pas vraiment de réponse à cette question. Mais cet après midi m'est venu l'idée de faire un système "à la Tapestry 5" en faisant donc un peu de magie :)

L'idée est de récupérer l'URL de la page sur laquelle on se trouve, de charger un javascript correspondant dans un path défini dans la configuration (une configuration pour toutes les pages du site, c'est pas trop dur, surtout qu'on pourra supposer par défaut qu'on se trouve à la racine ;oP), notamment pour qu'Archetype connaisse la racine du site, et l'endroit où on a voulu stocker nos fichiers correspondants au pages.

Rien ne vaut un exemple pour mieux comprendre :

La page appelée est
http://localhost/Archetype/WebContent/Start.html
On indique dans la configuration que toutes nos pages ont leur racine dans
/Archetype/WebContent/
... et que tous les JS correspondant à ces pages sont dans le répertoire (relatif au répertoire d'Archetype):
Pages/
Archetype va donc inclure le fichier
http://localhost/Archetype/WebContent/Pages/Start.js
... puis lancer la fonction:
Start.main();
(A noter que le Start.main a ce nom car il vient de la Page 'Start'. Sur la page 'Index', ce serait Index.main)

Conclusion, le main est lancé simplement en correspondance avec le nom de la page !

Je me suis donc empressé d'implémenter cette idée... et c'est à présent sur le SVN :)

Des nouvelles!

Après un mois de mai peu mouvementé, Swiip et moi même avons repris le développement.

Les priorités de Swiip sont:
  • Finir les "require": synchrone (tout type de fichiers), asynchrone basé sur callback (idem), et asynchrone multiple basé sur callback(les deux 1ers sont presque fini).
  • Commencer au plus vite la gestion de template (a minima avec celle de prototype, en rajoutant sans doute les boucles rapidement).

Les miennes sont:
  • Créer au plus vite les outils d'émission/réception des évènements. Les utiliser dans Archetype, notamment remplacer les callback par des évènements dans le require.
  • Mettre en place correctement tous les outils pour un développement propre : logger, évènements, tests unitaires, définition d'un composant (je reviendrai sur cette notion un peu spéciale dans un autre post, lorsque ce concept sera défini précisément ;) et mise en place de la structure pour en faire fonctionner.