1

fastIce php/redis web framework

source code can be found on github, also visit fastice.tk.




bon, j'ai nettoyé en profondeur mon bout de code, pour laisser l'essentiel, et j'en release une alpha smile
la licence est creative common by-nc-sa, bref, rien de commercial, on laisse mon nom et si vous le forkez il doit être distribué sous la même licence

si des personnes pouvais le tester, et me dire les défaut et choses manquantes ca serais cool,
à noter que je l'ai pratiquement repris de zero, et bon de truc on été dégagé et reviendrons petit à petit, la il n'y à que la base du systeme de template.

pour l'utiliser vous devez installer la base nosql redis ainsi que son client en module php, phpredis

installer redis sous ubuntu : sudo apt-get install redis-server
sous les autre distrib : http://redis.googlecode.com/files/redis-2.2.0-rc4.tar.gz décompresser puis faire make
pour le lancer automatiquement au démarrage, créer le fichier /etc/init.d/redis-server avec ce contenu en modifiant les path en conséquence

pour phpredis, tout est bien expliqué sur sa page.

pour utiliser le framework, décompressez le simplement comme n'importe quel autre site dans un répertoire situé dans le rep d'apache, en général /var/www/
ouvrez fastIce.php et customisez les qq define présent au début du fichier,
un template est présent et adapté au framework, il provient de ce site.
mis à part les css et images du template, son code html est dans "fr",

le framework utilise des squelettes de pages, qui ressemblent à ca : §header§§contenu§§footer§, ils sont présents dans fr/commun/skeleton/, un fichier ini présent dans fr/nomDePage/ indique au moteur quel squelette la page utilise, par defaut, le squelette est "normal"

les §§ entourent les bout de page, si par exemple §toto§ est trouvé n'importe ou par le moteur, il cherchera à la remplacer par un design nommé toto, ces design peuvent être présent en de nombreux endroits,

par exemple le design toto présent dans le design contenu, pour la page contact du template fr sera cherché dans fr/contact/contenu/toto.php, fr/commun/contact/contenu/toto.php, commun/contact/contenu/toto.php, fr/commun/toto.php, commun/toto.php, ou dans des clef redis en path eux aussi absolus et commun.
et si toto contiens lui même titi, les path absolue serons ajouté avec titi.

le moteur supporte l'utilisation de plugin, un plugin est similaire au designs à son insertion : §nomDuModule|arg1|arg2|..|argN§
un plugin est un répertoire contenu (par defaut) dans /modules/ et un fichier php du nom du plugin, le plugin rototo par exemple sera dans /modules/rototo/rototo.php, il devra contenir une fonction fn_rototo qui récupèrera un array contenant les arguments, un plugin ne sera chargé qu'une seule fois, mais peu être appelé un nombre illimité de fois dans vos pages.

tous les design et plugin serons mis en cache automatiquement par le moteur, tout ce qui est variable devra contenir <?php noDesignCache(); ?> pour empêcher la mise en cache.

si le paramètre deleteCache est fourni à une page, en get, l'ensemble des caches de toutes les pages serons détruits.

je n'ai volontairement pas remplis l'ensemble des designs des pages, pour montrer l'utilisation des répertoires communs de designs, également, deux plugins sont présent, un d'affichage de menu et un pour "editer" sommairement les fichiers de design.

à la première exécution du plugin menu, il créera des entrée dans redis pour avoir un menu "prerempli"

voila, en espérant que ca serve à quelqu'un et surtout que ca m'apporte des conseil et bonne idées pour le futur.
et la le mec il le pécho par le bras et il lui dit '

2

Et heuu en une phrase, fastice, c'est quoi?
avatar
納 豆パワー!
I becamed a natto!!!1!one!

3

idem : tl;dr, le post laisse penser qu'on est supposés savoir ce que c'est que fastice, et perso c'est la première fois que j'en entends parler grin
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

4

un framework php qui te fait jouer au légo avec tes pages, tout en te laissant tout contrôle sans aucunes obligations, un truc rapide et simple.
enfin c'est ce que j'ai essayé de faire cheeky
et la le mec il le pécho par le bras et il lui dit '

5

mouais, c'est pas très vendeur ton truc, et le fait que ça ne puisse pas être testé en 2 minutes sans installer plein d'autres trucs ça donne pas envie d'essayer ^^

t'as pas un exemple d'utilisation concret, une démo en ligne, un bout de code qui explique à quoi ça sert... ?

[edit] bon, j'ai relu le post, y'a un rapport avec smarty ou pas du tout ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

6

aucun rapport avec smarty, celui ci à son propre langage,
ici rien n'est imposé, tu continu à faire ton php classique,
la seule chose c'est qu'il te propose un découpage intelligent des pages,

include "footer.php" ?>
sans framework tu ferais <?php include "header.php"
print '<div id="contenu">';
// contenu de ta page
print '</div>
<div id="bandeau">';
// bandeau de la page
print '</div>';
§header§ <div id="contenu">§contenu§</div> <div id="bandeau">§bandeau§</div> §footer§ici, tes pages ont un squelette par exemple, pour reprendre la même chose qu'au dessus :un fichier ini optionnel (ou une clef redis) indique que telle page va utiliser tel squelette, il indique également le titre, les mots clef, descriptions, meta de ta page (optionnel également)

une page ne possédant pas de bout de page spécifique, par exemple le bandeau, utilisera celui commun, ici dans le bandeau par exemple nous mettons un menu, donc sauf cas particulier, nous n'avons pas besoin de le créer pour chaque page.

concrètement, en se disant que l'header, le footer et le bandeau sont commun à toute les pages, tu n'as plus que le contenu à spécifier, il suffit donc simplement de créer un repertoire de l'url de ta page dans le répertoire du template (dans l'exemple, "fr") et dans celui ci, un fichier nommé contenu.php

donc pour la page qui-sommes-nous (qui sera accessible depuis http://tonsite.truc/qui-sommes-nous)
tu crée le fichier /fr/qui-sommes-nous/contenu.php

dedans tu peu y mettre du code html et/ou php classique, d'autre bout de page avec simplement §nom-du-bout-de-page§, lancer un plugin, ou autre.

donc si tu marque simplement bonjour! dans le fichier, quant tu accèdera à la page qui-sommes-nous, une page complète avec son header, son footer, son bandeau avec son menu s'affichera, et dans le contenu de la page, tu y verra bonjour!

le moteur possède un cache de page utilisant redis, avec une clef de cache utilisé par page, ce qui fait que chaque fichier sera mis en cache si l'inverse n'est pas explicitement spécifié, redis étant très rapide, le moteur pourra te générer tes pages 'fixes' en moins de deux millisecondes.

une chose que j'ai oublié de spécifier hier soir, il y à d'autre mot clef à mettre dans ton design, généralement dans l'header, actuellement ces mot clef sont : 'head','js','jquery','title','meta','style','keywords','description'

à utiliser comme ceci : par exemple pour le titre, dans l'header tu mettra <title>[title]</title>

le titre sera importé depuis le .ini

si tu n'à pas de .ini le titre par defaut sera utilisé, également le moteur va te creer deux fonction par mot clef : setMotclef et addToMotclef, utilisable n'importe ou,

par exemple, si le titre défini dans le .ini est 'bonjour!' et que dans le footer (et que celui ci n'est PAS défini pour être mis en cache) tu met <?php addToTitle(' le monde smile'); ?>, le titre affiché de ta page sera bonjour! le monde smile, bien évidement si tu avais utilisé set au lieu de addTo, le titre aurais été remplacé et non concaténé.

ce qui est très utile par exemple avec les plugins ou des pages particulières, nécessitant certain javascript,

un coup de addToHead('mon-jolie-fichier-js.js'); te calera l'header js qui va bien dans ton head, sans autre manipulation, puis un coup de addToJs ou de addToJquery te permettra d'insérer la ou il faut ton code d'init etc ..

par exemple, le plugin manage inclus, utilise ces méthodes.

pour un site d'exemple, j'en mettrais un en ligne, ou mieux peu être faire une vidéo montrant l'utilisation.

oui tu est obligé d'utiliser redis, mais je le mettrais comme une option, (en réalité il ne sert pratiquement que au cache de page, et dans l'exemple, le plugin menu l'utilise, le moteur va essayer de chercher des designs de bout de page dedans aussi, mais c'est devenu inutile depuis le système de cache, de plus les design importé de ce stockage nécessitais l'utilisation d'eval)
et la le mec il le pécho par le bras et il lui dit '

7

Oki je vois, merci pour l'explication.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

8

version 0.42

* les squelettes et .ini des pages sont maintenant mis eux aussi en cache
* les mot clef spéciaux du render sont dorénavant également en cache, concrètement maintenant un plugin rajoutant du code js ou autre dans le head ou ailleurs peu être mis en cache, son js lié apparaitra dans le head. pour empêcher cette mise en cache ajout de la fonction noRenderCache(); à utiliser avant le addToJquery ou autre
* autre optimisations mineures

l'ajout de ?deleteCache sur une url va également supprimer ces nouvelles entrées du cache.
et la le mec il le pécho par le bras et il lui dit '

9

quelqu'un aurais une manière plus élégante pour créer des fonctions à la chaine ?
$renderWords = array('head','js','jquery','title','meta','style','keywords','description');
foreach($renderWords as $word)
{	eval('function addTo'.ucfirst($word).'($txt){ print ":)"; }');
}


edit, bon je l'ai ai mises en dur, j'ai gagné 0.3 - 0.5ms, bref je tombe sous les 1.5ms de génération de page Oo eval rame vraiment c'est dingue
et la le mec il le pécho par le bras et il lui dit '

10

0.43 out

- noRenderCache(); à été dégagé au profit du système de cache normal, les mots clef spéciaux du render ne sont plus mis en cache par page mais par bout de page
- amélioration du cache de squelettes de page et des .ini, le cache global de la page et ceux ci sont récupérés en même temps, ca réduit les requêtes redis de 3 à 2, dont une pipeliné
- amélioration et simplification du cache de design
- simplification et mise en dur des fonctions dédiées aux mots clef du render
- autres optimisations mineures
et la le mec il le pécho par le bras et il lui dit '

11

fallait l'appeler la version r0.43v
avatar
納 豆パワー!
I becamed a natto!!!1!one!

12

c'est pas faux grin
et la le mec il le pécho par le bras et il lui dit '

13

quelqu'un aurais des infos sur les namespaces css et/ou js ? (enfin si du moins ca existe et que c'est ce que je pense..)

la j'en suis à la gestion d'admin des modules, et j'ai peur que des conflits apparaissent, moi je fait gaffe, mais la création de modules et de leur admin étant très souple et simple, sait on jamais.
(en fait la j'utilise un double système de tabs pour afficher les admins, donc elle ne sont pas vraiment indépendantes vu qu'elles sont toutes affichées dans un div propre... bref tous leurs js et css se retrouvent dans le head.)

de plus existe t'il des techniques (à part tout passer en objets avec des private...) pour empêcher l'écriture de certaine variables php ?

laissant une liberté totale aux modules externes, ceux ci peuvent par exemple très simplement passer l'user logué en admin ..

vous allez me dire c'est pas demain que le pelerin moyen trouvera et utilisera un module malveillant pour ton truc sur le net, mais bon ca m'intéresse, je me demande comment font les autres framework/cms/trucmachin
et la le mec il le pécho par le bras et il lui dit '

14

je cherche a optimiser ce bout de code, j'ai dégagé le preg_replace_callback au profit de l'utilisation de strpos et str_replace, pour des grosse page je gagne 20% de perf globale, mais je pense encore pouvoir optimiser, notamment je voudrais dégager le substr_replace qui m'oblige à faire une copie de la sortie,

aussi, (pas taper :P) toute les chaines sont en utf8, et j'utilise pas les fonction mb_* ce qui fait que j'ai mis +2 et +4 (pas taper on à dit !! ^^) c'est grave ? ca peu m'entrainer des erreurs ? en fait je n'ai à détecter que le char § et la sur mes pages de test tout est au poil

bref, si qq connais deux trois subtilités qui font gagner des poils de cul, je suis preneur

	$offset=0;
	for(;;)
	{	$start = strpos($out,'§',$offset);
		if($start === false) break;
		$off = $start+2;
		$end = strpos($out,'§',$off);
		if($end === false) break;
		$size = $end-$off;
		$word = substr($out,$off,$size);
		$out = substr_replace($out,showPage($word),$start,$size+4);
		$offset = $start;
	}


sinon, petite page dédié au moteur, pas encore bien remplie mais bon :- ) http://fastice.tk
et la le mec il le pécho par le bras et il lui dit '

15

La logique d'optimisation en PHP n'étant pas la même que dans les autres languages, je me demande si un preg_match_all (voire un preg_replace_callback) ne serait pas plus rapide que toutes tes recherches. Ça dépend du nombre de remplacements à faire au total, mais s'il y en a beaucoup, alors les preg_* iront probablement plus vite même si elles utilisent des regexp.

(en règle générale, le langage est tellement lent que souvent une builtin lente est plus rapide qu'un bout de code algorithmiquement mieux optimisé)

Sinon les +2 et +4 c'est juste n'importe quoi, je ne sais pas trop ce que tu essaies de simuler avec ça, mais tu ne remplaceras pas le rôle de "mb_*" avec juste deux décalages d'offset, et ta fonction exécutée telle quelle sur de l'UTF-8 peut renvoyer des chaines invalides, tronquées, etc.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

16

en fait la seule chose que je doit détecter est '§', qui fait deux octets, le reste, je le manipule pas comme une chaine mais plutôt comme à l'ancienne, de la jolie mémoire, d'où l'utilisation des fonction non multibytes, je ne veut pas savoir que la partie que je remplace fait un char de moins que le nombre d'octet, je m'en tape, et ca n'aura pas d'incidence car j'utilise que des fonction qui tourne à l'octet,

vu que le seul char que je détecte fait deux octets, je décale donc mon "pointeur" de deux octets juste après celui ci, et à la copie pour dégager le premier et second § je remplace 4 octets de plus, ca c'est cool,

mon seul soucis est que je me demande si en fait strpos va bien détecter ce char § ou si en fait il va juste mater son premier octet, et si je risque d'avoir des faux positif m'obligeant a tester également l'offset+1 pour voir si ca correspond avec le second octet de § confus

j'ai pris strpos pour sa vitesse, le mb_strpos sera forcement plus lent et me renverra un offset "reel" pour lui mais pas pour moi, de plus mb_substr_replace n'existe pas, alors tintin pour faire mon remplacement final avec des offset pourris sad

après, si j'ai trop fumé et que je vois des bisounours partout sur le dos de l'éléphant bleu dite le moi de suite happy

concernant les deux écoles, preg vs strpos, justement jusqu'à présent j'utilisais preg_replace_callback, et ici avec le code du dessus je gagne ~20% en vitesse globale du script sur une grosse page, celle ci par exemple, sur une petite c'est beaucoup moins flagrant et négligeable, mais ca ne va jamais moins vite

après, ici je contrôle moi même la ou la recherche débute, alors que le preg_replace lui recommence du début à chaque fois, la grosse page fait 20ko de données, ca aide pas ^^ aussi preg_replace renvois un tableau à la fonction de callback, la méthode strpos non, juste la chaine, ca à un peu simplifié mon code, bref tout ca doit compenser les qq lignes de plus à parser ^^

edit > bon j'ai trouvé cette magnifique page détaillant bien ce qu'il va arriver en utilisant de l'utf8 avec les fonction non multibyte, bref ca à l'air ok
et la le mec il le pécho par le bras et il lui dit '

17

r043v (./16) :
mon seul soucis est que je me demande si en fait strpos va bien détecter ce char § ou si en fait il va juste mater son premier octet, et si je risque d'avoir des faux positif m'obligeant a tester également l'offset+1 pour voir si ca correspond avec le second octet de § confus

Ça marche parceque strpos ne recherche pas un caractère mais une chaine. En gros si ton code source est en UTF-8 (sick), alors le '§' de ton fichier source est un buffer de deux octets, donc ça trouve bien le '§' de ta string (ou plutôt les deux octets).

Le souci, c'est que potentiellement tu peux avoir un caractère codé sur 3 octets dont les deux derniers sont les mêmes que les 2 octets qui servent à coder un '§', d'où un faux positif : tu vas couper un caractère UTF-8 en deux, et produire un résultat totalement invalide. C'est peu probable, mais ça peut arriver.

Pour résumer, toutes les fonctions str* de PHP ne travaillent pas sur des chaines, mais sur des buffers d'octets. Si ton entrée et ta sortie sont dans le même encodage, par coup de bol ça marche donc assez souvent, mais tu risques quand même des bugs assez sournois qui vont te corrompre ta chaine quand ils vont arriver. Pour corriger ton code, il n'y a pas d'autre solution que d'utiliser des vraies fonctions qui travaillent sur de l'UTF-8.

Pour le coup de "la recherche débute", je comprends pas. Ton code ne fait qu'une seule passe sur la chaine, non ? (je ne vois qu'une seule boucle for). Du coup c'est exactement ce que ferait preg_replace, sauf que sa boucle for à lui tourne 20 fois plus vite que la tienne puisqu'elle est en C ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

18

Pour le coup de "la recherche débute", je comprends pas. Ton code ne fait qu'une seule passe sur la chaine, non ? (je ne vois qu'une seule boucle for). Du coup c'est exactement ce que ferait preg_replace, sauf que sa boucle for à lui tourne 20 fois plus vite que la tienne puisqu'elle est en C ^^
non car ce que ca va remplacer peu aussi contenir des morceaux a remplacer avec les §truc§, donc a chaque fois que j'en trouve un et que je le remplace je relance la recherche à l'endroit même ou j'avais trouvé et remplacé le dernier segment, le callback marchais très bien mais recommençais du début, après je peu aussi tester de faire du match_all remplacer tout et relancer tant qu'il n'y à aucun retour, mais vu que le preg_replace_callback étais bien plus lent et faisais exactement la même chose je suis septique, fait en C ou pas il ramais le cul
iwannabeamaki (./17) :
En gros si ton code source est en UTF-8 ( sick.gif )
spa bien l'utf8 ? sad
Le souci, c'est que potentiellement tu peux avoir un caractère codé sur 3 octets dont les deux derniers sont les mêmes que les 2 octets qui servent à coder un '§', d'où un faux positif : tu vas couper un caractère UTF-8 en deux, et produire un résultat totalement invalide. C'est peu probable, mais ça peut arriver.
ca c'est pas con, je n'y avais pas du tout pensé :/ il me reste à changer mon marqueur pour un à 4 octets alors ? quel bordel il faut un truc simple sur le clavier d'origine ^^
sinon je peu le doubler mais c'est con sad

cry
et la le mec il le pécho par le bras et il lui dit '

19

r043v (./18) :
non car ce que ca va remplacer peu aussi contenir des morceaux a remplacer avec les §truc§, donc a chaque fois que j'en trouve un et que je le remplace je relance la recherche à l'endroit même ou j'avais trouvé et remplacé le dernier segment, le callback marchais très bien mais recommençais du début, après je peu aussi tester de faire du match_all remplacer tout et relancer tant qu'il n'y à aucun retour, mais vu que le preg_replace_callback étais bien plus lent et faisais exactement la même chose je suis septique, fait en C ou pas il ramais le cul

Ah ok ton remplacement est récursif... dans ce cas en effet, pas d'autre choix que parcourir la chaine à la main :/
spa bien l'utf8 ? sad

Ben si mais pas pour le code source grin (déjà t'aurais pu choisir un caractère ASCII pour tes tags, parceque là c'est vraiment chercher les ennuis ^^)
ca c'est pas con, je n'y avais pas du tout pensé :/ il me reste à changer mon marqueur pour un à 4 octets alors ? quel bordel il faut un truc simple sur le clavier d'origine ^^

sick²

Non, faut juste coder proprement et arrêter d'essayer de parser une chaine UTF-8 avec une fonction non-UTF-8 pour gagner 3 poulièmes de secondes. Si tu voulais faire un truc rapide, fallait déjà pas choisir PHP tongue
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

20

ha oui, le premier bit en utf8 est toujours 1, l'ascii résoudrais mon problème ^^
mais je l'aimais bien mon § en plus son nom utf 8 étais "section", ca poutrait ^^
maintenant quel char est assez non utilisé pour être utilisé ? le $ c'est mort à cause de jquery, les { } ou [ ] pareil ...

bon, j'ai décidé de tester TOUS les char utf8, j'en suis au quart la

for($n=0;$n<=65535;$n++)
{	$start = $n<<16;
	$end = ($n+1)<<16;
	print '<br>['.$start.'] to ['.$end.'] ';

	ob_end_flush();ob_flush();flush();ob_start();
	$buf = '';$tstart = microtime(true);

	for($c=$start;$c<$end;$c++) $buf .= iconv('UCS-4LE', 'UTF-8//IGNORE', pack('V', $c));

	$found = strpos($buf,'§');
	if($found !== false)
	{	print '<b style="color:red;">found !</b> ';
		
		$offset = $found;
		while($f = strpos($buf,'§',$offset))
		{	if($f > 15) $sub = substr($buf,$f-10,20); else $sub = substr($buf,$f,20);
			$sub = str_replace('§','<span style="color:green;">§</span>',$sub);
			print '<span style="color:red;">"</span>'.$sub.'<span style="color:red;">"</span> ';
			$offset = $f+1;
		}
	}	else	print '<b style="color:green;">OK</b> ';

	print round((microtime(true)-$tstart),1).'s';
}
edit > ca c'est bizarrement stoppé au char 2138636288 mais jusqu'à présent aucun faux positifs
Si tu voulais faire un truc rapide, fallait déjà pas choisir PHP tongue

bah je m'étais un intéressé à ruby, mais il à pas l'air tellement plus rapide, et puis si je doit tout réapprendre, je suis pas près de gagner 4 ronds :/
après se démerder de faire un truc rapide avec un truc lent c'est cool, c'est comme pour le ti basic et limmt qui avais fait "red hat" sur la 89 happy

par contre, personne à fait de flib ou vertel version php ? :/

enfin bon, si php est le basic des langages web, je suis pas contre me faire indiquer l'équivalent du C tongue
et la le mec il le pécho par le bras et il lui dit '

21

Ruby c'est très lent aussi oui. Si tu cherches quelque chose de plus performant, en restant dans la même catégorie "gratuit", tu pourrais voir du côté de Python ou Perl (il y a bien Java, mais ça fait un peu trop "grosse artillerie"). À vue de nez, Python doit permettre de gagner un facteur 10 à 20 en performances par rapport à PHP ^^

Sinon tu peux aussi coder ton site directement en C, y'en a qui font ça (leboncoin par exemple), faut juste avoir un peu de temps devant soi grin (y'a même des frameworks MVC pour C++)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

22

un facteur 10 à 20 ? Oo
et la le mec il le pécho par le bras et il lui dit '

23

bon ben après avoir testé les 4 milliards de char, aucun n'est détecté comme § par strpos ^^
et la le mec il le pécho par le bras et il lui dit '

24

r043v (./22) :
un facteur 10 à 20 ? Oo

Yep, tu peux même afficher des gif fluides en 4 niveaux de gris oui

25

synchronisés avec l'écran ?

26

ça dépend du ping.

sinon je suis étonné qu'il y ait aucun moyen de faire des sites en java sans sortir un glassfish/tomcat/websphere.

27

version 0.5.3

- encore plus rapide
- meilleure gestion du cache, un seul appel à redis nécessaire
- support natif des langues
- support natif et automatique des url canoniques
- url rewriting 'interne'
- support de fichiers de 'constantes' contenant des bouts de page ne méritants pas un fichier à part entier
- ajout d'une fonction générique de remplissage de design depuis un tableau de tableaux de données, fillDesign
et de diverses autre fonctions l'utilisant qui importent les données depuis redis,
les version mysql viendrons quant je me serais decidé à le réinstaller
- optimisation de la détection et l'appel de modules
- ajout de nouveaux mot clef pour le render, [url] et [lang], il n'y à pas de fonction associées à ces mots clef contrairement aux autres
[lang] dans votre template se fera remplacer par la langue courante, idéalement à mettre dans la balise html : <html lang="[lang]">
[url] quant à lui se fera remplacer par la "racine" du site définie dans fastIce.php, exemple : <img src="[url]img/boldas-post-thumb.png"> il est la pour simplifier le rewriting d'url, qu'il soit fait par htaccess ou délégué à fastIce.


la prochaine version devrais contenir une gestion des dépendances entre modules,
le module "user" et "admin" arriverons très bientôt, après un petit regroupement et nettoyage de la partie "user", les droits utilisateurs sont également gérés.


fillDesign($data, $design, $callback=false)
data contient le tableau de tableau, design contient le nom du design à utiliser et remplir
callback contient soit une fonction qui va récupérer l'ensemble de la "ligne" de donnée et le mot clef à remplacer dans le design
} });
	exemple print fillDesign($data,'designtest',function($w,$d)
{	switch($w)
	{	case 'txt': return '<br><i>'.$d['txt'].'</i>'; break;
		case 'title': return '<br><b style="color:red;">'.$d['title'].'</b>'; break;


soit, un array de fonction,
$c = array(	'title' => function($dta){ return '<br><span style="color:red;">'.$dta.'</span>'; },
		'txt'  => function($dta){ return '<br><i>'.$dta.'</i>'; },
		'toto' => 'nl2br'
);

print fillDesign($data,'designtest',$c);
si le mot clef existe dans les données, la fonction reçois son contenu, sinon elle récupère l'ensemble de la ligne de donnée (mots clefs "virtuels")
si callback n'est pas défini, la fonction remplacera simplement les mot par leur contenus, un mot sans données sera remplacé par rien, ''
comme suggéré dans les exemples, la fonction retourne la série de designs remplis

redisHashFill($hashkey, $design, $callback=false)
cette fonction se charge de récupérer un hash redis et de remplir un design avec, similaire à fillDesign sauf le premier argument qui est la clef d'un hash redis

sredisHashFill($setkey, $design, $callback=false, $kprefix='', $ksuffix='')
cette fonction recupere un set redis, charge les hash pointé par celui ci et rempli une serie de design avec, le premier argument est la clef du set,
kprefix est le préfixe nécessaire pour recréer la clef des hash, ksuffix est la même chose mais son suffixe

exemple : le set contient "riri" "fifi" et "loulou" les hash corespondants selon le 'protocole' que vous avez choisi pour votre application est par exemple pour riri : "monsite:disney:riri:user" ici le prefixe sera "monsite:disney:", le suffixe quant à lui sera ":user"
bien évidement, si vous remplissez le set avec les clef complète, laissez le prefixe et le suffixe vide.

lredisHashFill($listkey, $design, $callback=false, $kprefix='', $ksuffix='', $start=0, $end=-1, &$size=0)
cette fonction récupère une liste redis (ou une partie de celle ci), va récupérer les hash correspondants et remplis une série de design avec, le premier argument est la clef de la liste
les préfixe et suffixe fonctionnent de la même manière qu'avec sredisHashFill
start et end définisse les limites de la partie à récupérer, les offset négatif fonctionnerons comme dans redis.
la variable passé en référence, si vous la passez, se fera remplir avec la taille totale de la liste (la gestion des pages vous est délégué)

je n'ai pas pour le moment réalisé de fonction équivalente pour les zset, leur utilisation pouvant être assez varié, vous pouvez néanmoins très facilement utiliser fillDesign pour afficher des données provenant de ce type de source.

getlang()
retourne la langue actuelle

getUrlPath()
retourne le path actuel (rewriting interne)

le rewriting par default considère que le premier sous répertoire est une langue, si la taille fait 2 char, autrement il sera le début du path
la dernière partie de l'url sera la page en elle même, avec .html ou sans extension,

concrètement : /fr/toto/titi/tata/truc/machin42/index correspondra à une page française, la page index sera traité, et elle recevra le path "toto/titi/tata/truc/machin42" attention, car /fr/toto/index ou /fr/index appellera exactement la même page, index, veuillez donc à traiter le path et afficher des données en conséquence.

chaque page sera mise en cache en tenant compte de sa langue et son path.

la langue "initiale" est à définir dans fastIce.php,
si celle ci est "fr" par exemple, les pages /fr/index, /index, /fr/index.html et /index.html serons équivalentes, leur meta url canonique pointerons toute vers /index
bien évidement si un path est aussi dans l'histoire, celui ci se rajoutera dans tous ce bordel et la canonique en tiendra compte.

le moteur va également chercher des designs dédié à la langue, si par exemple le squelette de page va chercher une partie nommé "content", il cherchera en priorité fr.content.php puis ensuite content.php, ceci est valable autant dans les répertoire commun que ceux spécifiques aux pages.

concernant les nouveaux fichiers de constantes, il peu y en avoir un collectif, dans le répertoire du template, nommé par default "constants.ini" et un par page, écrasant au besoin des constantes communes, il porte le même nom et doit se trouver dans le répertoire de la page,
ces fichiers ini contiennent plusieurs sections, une commune entre les langues, appelé "common" et une par langue disponible, nommé par deux lettre suivant donc, la langue

l = "truc bidule en"
exemple de fichier :[common]
designtest = "<span><b>$title$</b>$txt$</span>"
prddesign = "<div><span>$ref$, $nom$ : $prix$</span><div>$txt$</div></div>"
listdesign = "<div>$toto$</div>"

[fr]
blablacontact = "blabla"
animal = "truc bidule fr"

[en]
blablacontact = "en blabla !"
anima

et la le mec il le pécho par le bras et il lui dit '

28

r.',$page); ?>
fichier index.php<?php

$tstart = microtime(true); 
session_start();

include 'fastIce.php';

if(isset($_GET['p']))
	$pageToShow = $_GET['p'];
else	$pageToShow = 'index';

if(isset($_GET['path']))
	$urlPath = $_GET['path'];
else	$urlPath = '';

if(isset($_GET['lang']))
	setInfo($_GET['lang'],$urlPath);
else	setInfo(defaultLangage,$urlPath);

$page = renderPage($pageToShow,showPage($pageToShow));

session_write_close();

echo str_replace('[time]','generated in '.round(((microtime(true)-$tstart)*1000),3).' ms on this 1.6Ghz monocore, 2Gb ram serve


1&path=$2 [L,QSA]
fichier .htaccessRewriteEngine On
# direct page, default langage
RewriteRule ^([^/]+).html$ index.php?p=$1 [L,QSA]
RewriteRule ^([^/\.]+)$ index.php?p=$1 [L,QSA]

# level 2 direct page, default langage
RewriteRule ^([^/]{3,})/([^/]+).html$ index.php?p=$2&path=$1 [L,QSA]
RewriteRule ^([^/]{3,})/([^/\.]+)$ index.php?p=$2&path=$1 [L,QSA]

# page on dir level n, path support and default langage
RewriteRule ^([^/]{3,})/(.+)/([^/]+).html$ index.php?p=$3&path=$1/$2 [L,QSA]
RewriteRule ^([^/]{3,})/(.+)/([^/\.]+)$ index.php?p=$3&path=$1/$2 [L,QSA]

# page on dir level 2, langage support
RewriteRule ^([^/]{2})/([^/]+).html$ index.php?p=$2&lang=$1 [L,QSA]
RewriteRule ^([^/]{2})/([^/\.]+)$ index.php?p=$2&lang=$1 [L,QSA]

# page on dir level n, langage and path support
RewriteRule ^([^/]{2})/(.+)/([^/]+).html$ index.php?p=$3&lang=$1&path=$2 [L,QSA]
RewriteRule ^([^/]{2})/(.+)/([^/\.]+)$ index.php?p=$3&lang=$
et la le mec il le pécho par le bras et il lui dit '

29

le str_replace final ne prend pas trop de temps? grin

30

lol :- )
lui c'est la cerise, faut se faire un peu plaisir des fois happy
et la le mec il le pécho par le bras et il lui dit '