Folk·o·pedia top départ

Suite de l’article précédent sur le même sujet, mais cette fois de manière plus technique. Nous voilà déjà 7 mois plus tard… Rien n’a été fait si ce n’est ce mois de Mai, du coup décortiquons.

Comme dit précédemment, c’est un gros projet, ambitieux et novateurs à différentes échelles, et donc accompagnés de complexités et difficultés pour le démarrer/réaliser. Oui OK je me cherche quelques excuses mais elles sont véritables.

« Mais tout vient à point à qui sait attendre » un sage aurait-il dit; et c’est effectivement le cas : l’illumination du premier jalon. Je vais donc vous parler de ce qui porte le nom, actuellement, de Schema Definer ou le définisseur de schéma.

« Mais qu’est-ce donc ? » demande la foule tel un 42 en réponse d’une longue attente. Tout simplement notre première étape, car vous n’imaginiez quand même pas que le site pouvait se gérer sans structure ?

Aussi permissif le site, en objectif, sera; autant il lui faut une mécanique de définitions pour vous proposer celle-ci. Quelle belle phrase.

Récapitulons après ce blabla. Jusque là nous avons défini un schéma de base de données, donc un moyen de stocker de l’informations organisées selon une définition. Cette dernière décrit un ensemble de tables représentant notre infinie possibilité à décrire tout système folklorique.

Ça c’était il y a +2 ans, selon les idées sur les ontologies. Ensuite j’ai cherché le stack ultime du web de demain… Ok sans succès, on va partir sur un Angular/Lumen pour débuter. Mais je ne désespère pas de trouver le design du web de demain quand on attaquera le front (partie visible et utilisable).

Déjà le fait d’avoir simplifié et décidé du stack, ça soulage, beaucoup même. Je vous recommande Homestead via Vagrant pour démarrer avec simplicité.

Revenons à nos moutons après cette digression. On a de quoi stocker de l’information brute qui n’aura du sens que si on lui en donne, c’est le rôle du Schema Definer. Le schéma sémantique sur le schéma structurelle (stockage).

Si je stock 36, rien ne me dit que c’est mon age, sauf si une définition l’indique au système.

Là je vous ai perdu, entre logique effrayante et explications à rallonge.

Comme dit nous avons un système de stockage différent de ce que l’on a habituellement (relationnel, non relationnel structuré, …) où la conception contient le sens des données. Mais nous, non. Notre mécanique retiendra des nombres et chaînes de textes reliées entre elles, de manière relationnelle.

OK, c’est quoi ce schéma ? Tout simplement la définition de ce que l’on veut encoder sur Folkopedia : une personne, un groupe, un document, …

Pour faire simple, en expliquant sommairement la mécanique triplet RDF, vous aurez un objet/entité (virtuel), qui a des propriétés avec des valeurs.

De manière appliquée : je suis l’instance d’une Personne, ayant pour surnom : Killan. Le schéma précise qu’il existe une entité Personne, avec pour propriété possible un surnom qui sera de valeur texte.

La valeur pourrait être la référence d’une autre entité. Genre une entité livre peut avoir une propriété auteur qui a comme valeur la référence d’une entité personne. Etc.

Avec une table de 3 colonnes vous avez votre système, simple mais horriblement pas performant. Et on ne va pas entrer dans ces histoires-là ici. Le schéma Folkopedia est différent tout en suivant le principe et un futur système de cache fera le delta de performances. On reviendra dessus bien plus tard.

Pour revenir sur le Schema Definer, vous pouvez prendre exemple sur le site de schema.org qui est le premier objectif. Vous pouvez prendre l’entité Book (livre) comme exemple.

Pour résumer, on peut dire que le Schema Definer est une administration de la structure de données du site Folkopedia.

C’est pour ça que j’ai parlé d’Angular, il nous faut une interface pour manipuler ce schéma. Peut-être qu’un jour on exposera ce site, comme explication de la démarche scientifique, on verra, rien n’est figé actuellement. La démarche m’importe beaucoup.

Bref, là on a un Lumen installé sur un Vagrant/Homestead, tout frais, et cet articles un point de départ publique. C’est parti !

Comitards 3 : Folk·o·pedia

Cela fait presque 2 ans que c’est dans les cartons, et si on remonte à Comitards 2.3, bien plus encore. Ceci dit, c’est une attente justifiée vis à vis de l’important changement que cela cache. Évidemment, avec le hack du serveur et la perte d’articles, les derniers articles datant de la V2 et de Badawok, le blog manque d’actualité. On va corriger ça avec cet article.

L’idée de base est de pouvoir ajouter plus de types de contenu, ensuite de ne plus devoir modifier le site pour y arriver, et enfin, car je suis seul, que la communauté arrive à s’auto-gérer. En complément, tant qu’à faire, élargir/revoir l’idée de Comitards, profiter du retour d’expérience de l’idée et du site, et ainsi reforger le site entier.

Déjà le constat, le nom « comitard » est souvent mal compris, « Je ne suis pas comitard », et dans d’autres pays cela nécessite une explication. Du coup j’ai émis quelques idées et proposé une sélection à quelques proches concernés. Nous accueillons bien plus que des « comitards », il suffit de regarder les ordres en tous genres. Il s’agit en fait de concerner les acteurs et groupes des traditions, souvent festives. Le folklore dans son ensemble.

Folkopedia a été retenu, voyez y la contraction de folklore et d’encyclopédie, dit folk-o-pedia. Le ‘o’ me fait sourire, comme dans les imaginaires éthyl·o·trons, truc-o-matic, etc. qui contractionnent les mots entre-eux faisant naître un néologisme d’association.

La mécanique du site est également complètement mise à terre. Il ne s’agit pas de simplifier le schéma DB comme la dernière fois ou de faire le grand nettoyage en ajoutant ce qui manquait depuis la dernière fois, mais de repenser intégralement le système de base, et là j’ai été chercher loin.

Une de mes premières missions en tant que consultant au Luxembourg (vers 2011) m’a amené à découvrir les ontologies au travers d’une application dans le domaine de la recherche sur les tests assistés par ordinateurs (TAO/OAT). Très nébuleux pour moi, il m’aura fallu quelques recherches personnelles et un intérêt sur les métadonnées, avec un cours en prime, pour faire le lien avec Comitards. Évidemment pas au premier coup d’oeil.

Notez que j’avais tenté de normaliser le contenu de Comitards via RDF avec le projet FGPI : Folk Groups and People Involved vocabulary. Ceci, par manque de connaissance et de capacité de contrôle n’ira pas plus loin et restera probablement un brouillon intéressant sur un sujet ô combien difficile.

Ceci dit, je me base sur l’idée et non pas une application stricte, car les performances ne sont pas au rendez-vous et j’avais envie d’intégrer un cadre et des définitions pour le concept général. Du coup je repars sur une base de données relationnelles, un schéma spécifique et une optimisation par extraction des données. On aura un cache de lecture simplifié tandis que l’écriture se fera dans le système étalé. Du moins c’est comme ça que je vois la chose. Flexibilité totale et optimisation.

Pour ceux que ça intéresse, prenez toujours en compte l’usage. Combien vont écrire pendant que combien vont lire, que ça soit concurrent ou non. Sur un site comme Comitards, on a très peu d’écriture et beaucoup de lecture. Vous savez donc ce qu’il faut optimiser et pourquoi.

Avec ce nouveau schéma, plus besoin de modifier le site pour ajouter du contenu. Il suffit d’entrer les données du nouveau sujet, ses attributs et les liens possibles. Le tout sera fait via une zone d’admin (j’espère 🙂 ), mais ça reste l’idée.

Pour développer, un « quelque chose » (une photo, une personne, un groupe folklorique, …) est une entité, et celle-ci a des attributs (nom, date de création, histoire, …) et des liens vers d’autres entités (photos, documents, …). Le plus dur là dedans est la définition de chaque chose.

L’ensemble de cette réflexion est basée sur un cahier des charges regroupant tout ce que l’on souhaite intégrer, avoir une vue la plus claire possible du projet, des besoins, optionnels ou non. Ensuite, cela a été soumis à des volontaires de tous horizons, raffinant le premier jet jusqu’à obtenir quelque chose de correspondant à ces cibles. Merci à eux.

Dans cette continuité, merci mon Gros Lézard (Lord Suprachris), pour la belle prise de tête sur la conception du schéma de la base de données. Cela a été périlleux mais on a réussi à faire correspondre tout le cahier des charges en un seul schéma ! Et ça c’est pas rien !

Mais les prises de têtes ne sont pas finies, il y a encore un autre point important que je pensais définit depuis le début : le stack technologique. J’avais oublié un détail : je suis seul. J’avais imaginé un stack très développé, beaucoup de challenges et d’apprentissages, mais avec de telles envies, ce n’est pas demain que le site sortira.

C’est ma compagne, Boudine pour ne pas la citer, qui m’a remis les idées claires avec une réflexion sur le temps déjà passé, la difficulté que je me suis donné et l’inatteignable objectif. Du coup, à contre coeur, mais en sachant le bien fondé, j’ai revu le stack, du moins j’essaye. Il y a beaucoup de niveaux à décortiquer, mais je vais y arriver.

Enfin, car on arrive quand même au bout de l’état des lieux, il y a le design, lui aussi confiant dans les premières maquettes, mais aujourd’hui plus vraiment. Il faut attraper l’utilisateur dans une mécanique fort complexe et rendre ça sexy. Qu’il prenne plaisir à contribuer et à consulter. C’est chaud. Là aussi j’ai sollicité des avis, mais j’ai perdu mon auditoire tant ils se bloquent sur la complexité du projet. Je ne baisse pas les bras, je finirait bien par trouver cette nouvelle interface moderne et flexible capable de répondre aux attentes de Folklopedia.

C’est un peu comme dans Social Network (film de l’histoire de Facebook), j’en garde une phrase intéressante : « On ne sait pas encore ce que c’est ». On sait très bien ce qu’on a développé, bien sur, mais pas forcément ce que ça va ou peut devenir, son potentiel, ses usages et dérives en tous genres.

On en est là, entre une fin de post analyse et de début des travaux, avec un objectif de base débuté avant fin d’année. On avancera entité par entité, outil par outil, il y aura des refontes, des erreurs, des cris et des larmes, mais il y aura surtout un résultat à cette aventure complètement folle :

Numériser les traditions, enregistrer les vécus, préserver l’éphémère : L’encyclopédie folklorique.

VirtualBox déteste Sendfile

Je développe mes sites à l’aide d’un VirtualBox (debian, apache) et d’un répertoire local partagé. Cependant les fichiers ne sont pas toujours à jour. Cas typique d’un envoie d’image via formulaire et voir l’ancienne rester, or, en local l’image a bien changé. C’est à dire que VirtualBox a un soucis avec une particularité système : Sendfile.

La solution est de le désactiver directement dans votre apache2.conf en ajoutant la ligne suivante :

EnableSendfile off

Articles qui m’ont aidé :

VirtualBox Hates Sendfile

https://www.virtualbox.org/ticket/9069

 

Badawok 7.x ne meurt jamais

Pourquoi diable un article sur Badawok 7.x ? Car en fait je l’utilise encore et continue de faire progresser sa branche, même si la 8 a été démarrée. D’un côté car il est en prod et qu’il faut suivre parfois les petits couacs potentiels, et puis, surtout, car je développe un nouveau site client, et donc, avec une version stable et pas en dev, comme je peux me le permettre avec Comitards.

Que dire ? Plein de trucs !

Depuis le début de la 7, une page peut prévoir des remplacements, textes pour 99% de l’utilisation mais également d’insertion de module, via les accolades ( {class:method|params|...} ). Une erreur a été corrigée au niveau de la détection des params, jamais utilisé jusqu’ici, et très fortement utilisé dans mon projet actuel. Quatre ans plus tard, une fonctionnalité voit son plein potentiel, et ça fait plaisir !

De même, une bonne surprise de conception, l’ordre des étapes de rendu permet de passer des arguments via PHP : {class:method|params|<?php echo $maVar ?>}.

Ainsi une problématique récurrente a pu trouver une nouvelle solution : la traduction de données.

Le système de langue étant dynamique, le nombre de langue varie et la maintenance de formulaires est pénible, coté front et coté code avec les checks etc. On découpe tout ça autrement.

Brutalement on imagine une table avec un seul id, mettez ce que vous voulez comme champs, excepté du texte. Coté formulaire vous ne vous occupez que de vos champs et vous insérez là où vous voulez l’appel au système de traduction ({trad:displayOne|params}) les params pouvant définir, dans un ordre définis, l’id du champs, son maxlength, etc. Je vous passe les détails.

Dynamiquement le formulaire sera complété de vos champs et ceux-ci seront pré-rempli si existant. Côté back, 2 méthodes, une de check des required et langue par défaut et une de sauvegarde multi-lingue.

Maintenance plus aisée, tant pour l’utilisateur que le développeur 🙂 !

Avec le même système d’insertion de module, et sur retour d’expérience du site terragusto.be, où la colonne de gauche devait être préparée par chaque action, ici notre menu/sous-menu principal est composé de 3 insertions, un par menu. Ainsi on ne met pas de code dans le layout non nécessaire et le rendu de manière centralisée avec les appels préparatoires qui vont bien et toujours les ACL qui vont avec.

Encore un autre usage et amélioration, la barre d’admin, d’habitude dans le layout sur condition ACL (Access Control List) et ici en centralisé avec config pour le global et la possibilité à chaque action de déclarer un menu potentiel, dont l’ACL activera ou pas l’affichage.

Enfin, un système de message d’erreur ou confirmation centralisé, inspiré de l’univers ZF. On envoie le message, on le configure pour son apparence et hop, le prochain affichage possible les affichera selon le template défini.

Cette version a encore du poil de la bête et n’a pas encore tout donné, c’est un plaisir personnel de voir son propre framework capable et fonctionnel :).

IE10:page-break-inside vs print

J’ai développé une application web de gestion des évaluations du personnel. Ceux-ci impriment leur évaluation, et dans toutes grandes entreprises, il n’y a pas un type de poste mais autant que d’employé 🙂 , surtout quand ils accèdent depuis l’extérieur.

J’ai opté pour Bootstrap sur un Zend Framework 2 et une impression naturelle de la page web plutôt que de générer un PDF. Pourquoi faire 2 fois le travail quand il suffit d’un peu de CSS :).

C’est là qu’on me dit que rien ne va quand on imprime, que le nombre de pages est infini, etc. L’utilisateur dans sa splendeur 🙂 rien ne va mais tout va SAUF l’impression sous Windows 8.0 et IE10.

Après une recherche dichotomique pour isoler le méchant code, voici le meurtrieur de navigateur avec sa solution, hop tout en un.

.container .tab-pane {
    page-break-after: always;
    page-break-inside: avoid;
}
.ie10 .container .tab-pane {
    page-break-inside: auto;
}

Le page-break-inside, qui date de IE8 en terme de support, a une belle régression ici et ne s’y retrouve plus, générant ainsi une infinité de page, pète la mémoire et fin de l’histoire, ça ne sort jamais.

Il vous faudra également un petit JS trouvé sur le net qui aidera à la détection de IE10 qui ne peut plus se faire avec les commentaires conditionnés (<!–[if lt IE 9]><![endif]–>).

if (/*@cc_on!@*/false && document.documentMode === 10) {
    document.documentElement.className+=' ie10';
}

Source : http://www.impressivewebs.com/ie10-css-hacks/

Remettre la propriété en auto lui permettra de reprendre ses esprits et de faire son impression.

[jQuery] Self clic & child force click

$('.category-blocs li').click(function(e){
    if (!$(e.target).is('a')) {
        $(this).find('a')[0].click();
    }
}).addClass('clickable');

L’idée est une liste avec du contenu, contenant un lien, et on veut que tout le <li> soit clickable. Hors on ne mettra pas des éléments bloc dans notre lien <a>.

Une solution javascript serait de dire au <li>, lors du click, de chercher l’enfant <a> (considéré seul ici, ou le premier trouvé) et de forcer le click de ce lien.

Too much recursion

Premier problème, ça boucle sur lui même et pète. Un effet de propagation (bubbling) que l’on échappe grâce à un test sur le target.

http://stackoverflow.com/questions/5967923/jquery-trigger-click-gives-too-much-recursion

Force click

Si vous targetez directement l’événement du lien comme ceci :

$(this).find('a').click();

cela ne donnera rien, vous devez prendre l’élément du DOM et non l’objet jQuery.

http://stackoverflow.com/questions/5838241/jquery-force-click-href

OVH, GMail et l’envoie de mail

Prenons le cas où vous avez votre domaine, vous configurez un compte mail et le raccordez à un compte GMail pour plus de facilité. Classique.

D’un autre côté vous avez votre serveur et vous envoyez des mails avec le même compte mail.

Et bim, vous voilà avec un compte bloqué !

OVH sécurise vos comptes mails en surveillant la provenance de connexion. GMail est en Amérique et votre VPS (par exemple) en France, du coup, en même temps vous êtes connecté à 2 endroits = piratage de compte détecté.

Une fois que ça vous arrive, ils vous suffit de déclarer un incident chez OVH et de leur expliquer la situation. Ainsi, plus de soucis.

Évidemment, cela n’arrive que dans le cas où votre GMail rapatrie ou envoie des mails pendant que votre serveur effectue également un envoie de mail. Mais c’est toujours bon à savoir.

Notez que pour débloquer votre compte il vous faudra vous rendre dans votre manager et saisir un nouveau mot de passe (ou le même). 5 à 10 minutes plus tard le statu sera revenu à la normal.

PHPMailer sur OVH en SMTP/POP3

Suite au fait que les emails envoyés par certains de mes sites ne sont plus reçus, j’ai cherché et trouvé une solution qui fonctionne conformément à mes attentes.

Contexte : VPS sur OVH, domaine OVH qui pointe vers ce VPS.

Première chose, j’utilisais déjà PHPMailer, une version précédente et domaine configuré pour SPF et DKIM. Donc mise à jour vers la source github de PHPMailer.

OVH n’est pas clair dans sa documentation quand vous en trouvez une qui est cohérente avec le reste et à jour. Basez vous sur le mail reçus lorsque vous créez votre compte. Le mail vous donne les ports et adresses à utiliser ainsi que l’indication très importante : connexion POP3 avant SMTP.

Par bonheur, la doc de PHPMailer fourni un exemple complet en ce sens.

//Authenticate via POP3.
//After this you should be allowed to submit messages over SMTP for a while.
//Only applies if your host supports POP-before-SMTP.
$pop = POP3::popBeforeSmtp('pop3.example.com', 110, 30, 'username', 'password', 1);

//Create a new PHPMailer instance
//Passing true to the constructor enables the use of exceptions for error handling
$mail = new PHPMailer(true);
try {
    $mail->isSMTP();
    //Enable SMTP debugging
    // 0 = off (for production use)
    // 1 = client messages
    // 2 = client and server messages
    $mail->SMTPDebug = 2;
    //Ask for HTML-friendly debug output
    $mail->Debugoutput = 'html';
    //Set the hostname of the mail server
    $mail->Host = "mail.example.com";
    //Set the SMTP port number - likely to be 25, 465 or 587
    $mail->Port = 25;
    //Whether to use SMTP authentication
    $mail->SMTPAuth = false;
    //Set who the message is to be sent from
    $mail->setFrom('from@example.com', 'First Last');
    //Set an alternative reply-to address
    $mail->addReplyTo('replyto@example.com', 'First Last');
    //Set who the message is to be sent to
    $mail->addAddress('whoto@example.com', 'John Doe');
    //Set the subject line
    $mail->Subject = 'PHPMailer POP-before-SMTP test';
    //Read an HTML message body from an external file, convert referenced images to embedded,
    //and convert the HTML into a basic plain-text alternative body
    $mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));
    //Replace the plain text body with one created manually
    $mail->AltBody = 'This is a plain-text message body';
    //Attach an image file
    $mail->addAttachment('images/phpmailer_mini.png');
    //send the message
    //Note that we don't need check the response from this because it will throw an exception if it has trouble
    $mail->send();
    echo "Message sent!";
} catch (phpmailerException $e) {
    echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
    echo $e->getMessage(); //Boring error messages from anything else!
}

Il vous suffit de mettre les valeurs qui vous sont transmise et … ça n’ira pas encore.

Il va vous falloir vous connecter également à SMTP.

//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//Username to use for SMTP authentication
$mail->Username = "yourname@example.com";
//Password to use for SMTP authentication
$mail->Password = "yourpassword";

Il vous suffit de modifier SMTPAuth de false à true et d’ajouter les 2 lignes et c’est fini !

Badawok

Note à ceux qui utilisent le framework badawok (v7 dans mon cas), vous aurez un conflit entre votre classe mailer et base_mailer car badawok utilise déjà un PHPMailer.

Supprimez l’extend de la classe base_mailer et ajouter les require_once des classes : phpmailer, smtp et pop3. Créez un répertoire vendor dans votre projet pour y mettre proprement les 3 classes de PHPMailer et le tour sera facilement joué.

La v7 étant uniquement patchée pour le moment, cette modification ne sera pas répercutée.

Badawok 7.1 & dev.Comitards

Pendant un temps, une hésitation fût, au sujet d’un passage vers GIT, tenté avec succès puis au sujet de rester là où on a commencé, sur SVN, que nous avons finalement gardé. Ceci à titre anecdotique. Une des raisons majeure est la simplicité d’un système connu et qui convient ainsi que la bonne intégration dans notre univers de développement.

Badawok 7.1 a été corrigé en passant sur dev.Comitards à titre de test. Les deux ont ainsi pu être restauré, testé et fonctionnel.

Il ne restait que 2-3 broutilles qui ont été vite réglées, tout va donc pour le mieux.

Comitards pourra désormais tirer partie des nouveautés et Badawok, profitant de l’expérience, pourra évoluer.

Comitards 2 + Badawok

Nous en parlions fin janvier, un projet utilise la dernière version de Badawok, il s’agit de www.comitards.be 2.0. Il se porte comme un charme !

Cela a notamment aidé aux divers affinage du code et correction de bugs.

Il est donc fonctionnel, MAIS ne sera pas releasé en l’état tant que la seconde partie, l’édition en direct, ne sera pas finie. Cela laisserait trop de crasse, code non fini et ne serait pas correcte.

Le travail continue, un peu au ralenti mais en bonne voie !