Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Il s'agit dans un premier temps de proposer une "armature" qui exploite au maximum les possibilités du ZF. Plutôt blog, dans un premier temps, pour se concentrer sur la qualité.
L'autre axe principal est la modularité, si le projet évolue (vers un CMS), j'aimerais qu'on propose un système de plugins qui tient la route, simple et carré, avec des élements utilisables indépendamment.
Y a-til des domaines de compétences ou des classes ZF que tu maîtrises plus que d'autres, et sur lesquelles tu souhaiterais te pencher plus spécifiquement ? Idem pour Yannux (même si on en a déjà discuté...) ?
Hors ligne
Je peux peut être regarder du coté de Zend_Search pour faire un moteur de recherche. voir comment faire pour qu'il soit utilisable par n'importe quel module.
Ou la gestion d'i18n en fonction de la manière dont on le gère.
Il faudrait que l'on puisse s'organiser correctement pour développer le shimilibilik
Hors ligne
Pour info, il y a aussi Ralph Schinler qui bosse sur ZFPublish un module de blog.
Je ne pense pas que ce soit une bonne idée d'avoir un blog évolutif vers un CMS. Un CMS gère du contenu dans une arborescence de page mais peut aussi intégré dans ses pages des modules dynamiques comme des actus ou un blog.
Hors ligne
@Ndesaleux :
Je vais commencer à tracer les différentes interventions et les tâches assignées. Je m'occupe de vous proposer un support de travail ad hoc
Si possible, penche toi en priorité sur Zend_Translate, il faudrait que ça soit un minimum opérationnel lorsqu'on attaquera les vues (entre autres). Zend_Search est crucial, également, je te laisse t'organiser et faire des propositions.
Merci par avance pour ton aide.
Autre chose, connaissez vous un graphiste/designer qui aurait envie de proposer une charte graphique par défaut ? C'est nettement moins urgent, mais il serait sympa d'avoir une interface d'admin qui a de la gueule
Bref, les candidatures seront étudiées avec intérêt, faites passer le message !
Bonne soirée,
Dernière modification par thomas (06-08-2007 20:28:19)
Hors ligne
@2mx : en fait, la démarche est plutôt inverse, on reprend un peu la philosophie du framework lui-même, puisque le moteur de blog est une première brique ; il ne se complexifierait pas forcément vers un CMS, mais pourrait s'associer avec de nouvelles briques pour en créer un, avec une unification au niveau de la vue. Qu'en penses tu ?
Hors ligne
Oki, je m'oriente coté Zend_Translate, je pense que je vais partir sur TMX
plus pratique que l'utilisation de tableau ou CSV
moins complexe que gettext
l'inconvenient sera surement pour l'intégration d'une nouvelle traduction.
je vais étudier un peu plus les différents choix que propose Zend_Translate
je vais je pense aussi faire un module permettant de gérer les traductions de modules
Hors ligne
@ yannux : Bonne nouvelle, peux tu à l'occasion nous diffuser un MPD (en reverse engineering avec DBDesigner, par exemple).
Et oui, OK pour la GPL.
@ndesaleux : ça roule, tu pourras nous faire une proposition plus détaillée quand on aura une gestion de projet digne de ce nom
Hors ligne
thomas a écrit:
@2mx : en fait, la démarche est plutôt inverse, on reprend un peu la philosophie du framework lui-même, puisque le moteur de blog est une première brique ; il ne se complexifierait pas forcément vers un CMS, mais pourrait s'associer avec de nouvelles briques pour en créer un, avec une unification au niveau de la vue. Qu'en penses tu ?
C'est que je voulais dire
Hors ligne
Salut,
Si ça vous convient, je vais étudier l'organisation des vues, des layouts et la possibilités d'implémenter des view_helpers pour gérer, par exemple, l'affichage des formulaires, des listes, etc. Si vous avez des contraintes de votre côté en lien avec les vues, n'hésitez pas à me les transmettre.
A ce propos, dans l'appli actuelle, les différentes vues sont insérées dans un layout (view/scripts/layout) via un controller_action_helper (My/ViewRenderer/LayoutRenderer.php). Du coup, le layout dépend du module appelé, et peut être différent pour chaque module (intéressant dans le cas d'un module "admin", qu'il faudra prévoir).
En vrac :
- avez vous déjà testé le CNZ Framework (http://www.citadelnetwork.com/open/php/cnzframework/) ? Qu'est-ce que ça vaut ?
- pouvez-vous parcourir le bootstrap (www/index.php) et suggérer des modifications si cela vous semble nécessaire ?
- avez-vous un générateur de documentation préféré ? Honnêtement, je ne suis pas utilisateur jusqu'à présent, donc si il n'y a pas de préférences, je propose phpDocumentor...
Merci par avance,
Bonne journée
Dernière modification par thomas (07-08-2007 14:11:55)
Hors ligne
disons que j'ai un projet (qui depuis que j'ai essayer ZF est totalement restructurer virant la plupart des libraire développer pour les remplacer par celle de zend ... ), comme je ne pense pas que je saurait sortir ce projet avant longtemps vu que j'ai des études qui me prenne du temps ...
Donc c'est bien vers le système cms ou autre que vous visez avec au début juste un blog
Les dossiers je les organiserait +- comme ceci : http://framework.zend.com/manual/fr/zen … dular.html
avec en plus un répertoire lib -> pour zend et les fichier a ajouter (genre bbcode, smileys et autres trucs génériques utilisé dans divers module)
Dans ce cas il y a 2 système de plugins :
-> les autres modules (livre d'or, feuille de contact, recette de cuisines, forum, ...)
la un simple listing des différents dossiers, avc un résultat en cache pour l'optimisation, suffit!
-> les plugins de chaque module
il suffit d'ajouter les différents plugins aux répertoires, de lister et mettre en cache et dans le gestionnaires même si ils faut que l'utilisateur ajoute du codes, il l'ajoute via un message lui explicant quoi faire.
Pour l'admin il suffit d'ajouter un module admin, qui recevrait des controller qui étendent les autres contrôleur des modules
C'est simple a mettre en place et rapide!
Hors ligne
Salut à tous, j'ai fait une premiere rapide ébauche de gestion de traduction :
<?php require_once 'Zend/Translate.php'; class Api_i18n{ private $_pathApplication = ''; private $_pathModules = ''; private $_defaultLanguage = 'en'; private $_defaultAdaptator = 'tmx'; private $_terms = array(); /** * Set _pathApplication to $path * * @param string $path */ public function setApplicationDirectory($path){ $path = (string) $path; if ( false == self::testDirectory($path) ){ throw new Exception(); } $this->_pathApplication = $path; } /** * Get value of _pathApplication * * @return unknown */ public function getApplicationDirectory(){ return (string) $this->_pathApplication; } /** * Set _pathModules to $path * * @param string $path */ public function setModulesDirectory($path){ $path = (string) $path; if ( false == self::testDirectory($path) ){ throw new Exception(); } $this->_pathModules = $path; } /** * Get value of _pathModules * * @return string */ public function getModulesDirectory(){ return (string) $this->_pathModules; } /** * Test if $dir is a path of a directory * * @param string $dir * @return boolean */ public static function testDirectory($dir){ $dir = (string) $dir; if ( in_array($dir, array('.','..','')) ){ return false; }elseif( ! is_dir($dir) ){ return false; } return true; } /** * Set the default language * * @param string $language */ public function setLanguage($language){ $language = (string) $language ; if ( $language != '' ){ $this->_defaultLanguage = $language ; } } /** * Get the default language * * @return string */ public function getLanguage(){ return (string) $this->defaultLanguage ; } /** * Set default adaptator * * @param string $adaptator */ public function setAdaptator($adaptator){ $adaptator = (string) $adaptator; switch( strtolower($adaptator) ){ case 'tmx' : case 'gettext' : case 'csv' : case 'array' : $this->_defaultAdaptator = $adaptor; break; default : break; } } /** * Get default adaptator * * @return string */ public function getAdaptator(){ return (string) $this->_defaultAdaptator; } /** * Add an translate adapter * * @param string $item * @param string|null $subItem * @param array|null $param * @return boolean */ public function addTranslation($item, $subItem = null, $param = null ){ if ( isset($param) && is_array($param) ){ if ( isset($param['adaptator']) ){ $adaptator = (string) $param['adaptator']; }else{ $adaptator = $this->_defaultAdaptator; } if ( isset($param['language']) ){ $language = (string) $param['language'] ; }else{ $language = $this->_defaultLanguage; } } if ( strtolower($item) == 'application' ){ $path = $this->_pathApplication ; }else{ $path = $this->_pathModules.'/'.$item ; } $adaptator = strtolower($adaptator) ; $path .= '/i18n/'.$adaptator.'/' ; switch( $adaptator ){ case 'gettext' : $patternFile = '#([a-z]+)-'.$language.'\.mo#' ; break; case 'tmx' : $patternFile = '#([a-z]+)\.tmx#'; break; case 'array' : // A Déterminer $patternFile = ''; break; case 'csv' : $patternFile = '#([a-z]+)-'.$language.'\.csv#' ; break; default : return false; } if ( isset($subItem) ){ $filename = $path.str_replace(array('#','([a-z]+)', '\.'), array('', $subItem, '.'), $patternFile ); if ( file_exists( $filename) ){ $this->_terms[$item][$subItem] = new Zend_Translate($adaptator, $filename, $language); }else{ return false; } }else{ $dir = opendir($path); while (false !== ($file = readdir($dir)) ){ if ( preg_match($patternFile, $file, $match) ){ $subItem = $match[1]; $filename = $path.str_replace(array('#','([a-z]+)', '\.'), array('', $subItem, '.'), $patternFile ); if ( file_exists( $filename) ){ $this->_terms[$item][$subItem] = new Zend_Translate($adaptator, $filename, $language); } } } } return true; } /** * Get translation from $item, $subitem and $term * * @param string $item * @param string $subItem * @param string $term * @return string */ public function item($item, $subItem, $term ){ if ( isset($this->_terms[$item][$subItem]->_($term) ) ){ return $this->_terms[$item][$subItem]->_($term) ; }else{ return ''; } } }
je ne l'ai pas testée.
Elle est censée fonctionner avec n'importe quelle adaptateur de Zend_translate.
Elle a cependant des contraintes :
les traductions de l'application doit forcement respecter des contraintes sur leur emplacement et leur nom.
en étudiant la classe, c'est assez simple a comprendre.
si vous avez des questions, ou des interrogations quant à la classe y a pas de soucis, ce n'est qu'un premier jet.
Utilisation de la classe.
$translate = new Api_i18n; $translate->setModulesDirectory('/path/to/application'); $translate->setApplicationDirectory('/path/to/application/modules'); $translate->addI18n('application'); // charge toutes les traductions de la langue par défaut de l'application $param = array('language' => 'fr'); $translate->addI18n('blog', 'admin', $param); // charge la traduction fr de la partie admin du module blog // on passe l'objet à la vue $this->view->translate = $translate; // dans la vue on l'utilise comme ceci echo printf( $this->translate->item('blog','admin','addAnUser') );
Dernière modification par ndesaleux (07-08-2007 20:38:12)
Hors ligne
@grummfy :
Merci pour ces infos, je vais méditer dessus. Reste que je ne visualise pas trop tes "systèmes de plugins" : tu aurais un petit schéma/des précisions ?
@ndesaleux :
Ca me paraît très bon, mais j'ai quelques questions :
-> au sein de la classe, pourquoi ne peut-on pas remplacer ::testDirectory($dir) par un simple is_dir ?
-> au sein de la vue, pourquoi rappeler le contexte ('blog', 'admin') alors qu'il est précisé lorsqu'on charge la traduction ($translate->addI18n...) ?
De prime abord, je verrais bien la phase d'instanciation/paramétrage dans un controller_plugin. D'autre part, je pense qu'on peut encore simplifier l'utilisation (du type echo $this->translate('hello') ) en passant par un view_helper. Donne moi ton avis là-dessus.
Ah oui, et tu as dû indiquer :
$translate->setModulesDirectory('/path/to/application');
au lieu de
$translate->setApplicationDirectory('/path/to/application');
A+
Dernière modification par thomas (07-08-2007 19:44:47)
Hors ligne
Ok avec thomas pour le view helper, en mettant l'objet translate dans le registry.
Prévoir un view helper avec un mode return et un mode echo non ? Parfois c'est pratique et ça évite un echo dans la vue.
Hors ligne
Je vais voir pour le view helper
::testDirectory($dir), en fait je veux aussi vérifier si le repertoire est accessible mais j'ai eu un gros trou et la flemme de regarder comment faire
au sein de la vue, pourquoi rappeler le contexte ('blog', 'admin') alors qu'il est précisé lorsqu'on charge la traduction ($translate->addI18n...) ?
Ca permet de faire des espaces de nom et permettre ainsi d'avoir plusieurs traductions possibles pour une même clé.
par exemple on peut avoir la possibilité de faire plusieurs fils RSS, un pour le fil des billets du blog et un autre pour les commentaires d'un billet
on pourrait donc avoir
$this->translate->item('blog', 'news', 'feedIt') // Suivre les actus du blog $this->translate->item('blog', 'comment', 'feedIt') // Suivre les commentaires de ce billet
Bon on pourrait mieux les nommer et avoir feedNews et feedComment mais c'est pour expliquer l'idée.
Au fait, ca été codé a l'arrache et je me pose plusieurs questions :
-> Est ce que je garde mon idée d'espace de nom ?
-> Dois je faire une classe Exception spécifique
-> Est ce que je dois lever des exceptions à chaques erreurs possibles, ca me semble incorrecte car si une traduction n'existe pas on doit qd meme avoir la possibilité de voir quelques choses.
-> Niveau conception, y aurait surement des choses à revoir, je suis ouvert à toutes critiques
je conseille cependant toujours à utiliser printf ou sprintf car on pourrait avoir des parties variables dans les traduction :
printf($this->translate->item('application', 'interface', 'hello'), $nom, $date);
pourrais donner en FR :
Bonjour thomas, on est le vendredi 20 aout 2007
et en EN
Hello thomas, today is friday, the 20th august 2007
$date pouvant être lui meme une traduction
Ca sera simplement une habitude a prendre.
@thomas, merci pour la correction, ca été modifié
Dernière modification par ndesaleux (07-08-2007 21:28:15)
Hors ligne
yannux a écrit:
Ok avec thomas pour le view helper, en mettant l'objet translate dans le registry.
Prévoir un view helper avec un mode return et un mode echo non ? Parfois c'est pratique et ça évite un echo dans la vue.
Je pense qu'on peut même faire sans Registry, il est possible d'accéder à $view->translate au sein du helper avec cette technique : http://fashion.hosmoz.net/post/2007/07/ … iew-helper
@ndesaleux : Pour le formattage de chaîne (printf), j'en vois bien l'intérêt, mais rien ne nous empêche de le réaliser dans le view_helper, du coup l'expression est réduite au minimum au sein de la vue.
Dans le même ordre d'idée, on pourrait avoir un contexte/namespace par défaut :
$this->translate('hello', array($nom, $date))[/b]
avec la possibilité d'en préciser un autre :
$this->translate('hello', array($nom, $date), 'blog', 'comment')
Le tout étant géré dans le helper.
Pour les exceptions, je suis d'accord, il est acceptable d'afficher le terme par défaut si aucune traduction n'est dispo.
Hors ligne
Pour les exceptions, je suis d'accord, il est acceptable d'afficher le terme par défaut si aucune traduction n'est dispo.
Zend_Translate fait déjà ça je crois...
Hors ligne
Ouaip, il le fait par défault, mais c'était plutot au niveau de la configuration/initialisation de ma classe car si Zend_Translate n'est pas instancié il ne peut pas renvoyé le terme traduit / à traduire
Hors ligne
J'aimerais votre avis à propos de la gestion des formulaires, aspect qui m'intéresse particulièrement.
Utilisez-vous déjà les view_helpers par défaut pour les afficher, ou d'autres composants plus avancés ?
J'utilise pour ma part un composant maison qui gère l'affichage, la validation, le multipages, etc. mais il était convenu avec Yannux qu'on essayait de "ZFiser" cet aspect au maximum.
A quoi va votre préférence :
- étendre les view_helpers par défaut pour gérer "seulement" l'affichage, avec par exemple (dans la vue) :
$this->addForm(); $this->addField('text', 'montexte', ...); etc.
A noter que tout l'aspect validation est alors géré indépendamment dans le controller (ou le model, à confirmer).
- créer un composant piloté au sein du controller qui génère l'affichage et la validation, et qui reste en session le temps de son utilisation (l'équivalent Zfien du composant que j'utilise habituellement en somme). Je redonne mon exemple trés simplifié du début de thread (dans le controller) :
public function editAction() { if (isset($form_submitted)) { /* Update */ } else { $myform = new Form(); $myform->addPage(); $myform->addField("titre", [...]); [...] $this->view->form = $myform; } }
- un autre idée ?
Hors ligne
Je viens de voir ce post : http://www.z-f.fr/forum/viewtopic.php?pid=1553
=> ça va certainement répondre au besoin qu'on évoque, avec Zend_Form. Zend_Layout est crucial également.
Hors ligne
thomas a écrit:
Je viens de voir ce post : http://www.z-f.fr/forum/viewtopic.php?pid=1553
=> ça va certainement répondre au besoin qu'on évoque, avec Zend_Form. Zend_Layout est crucial également.
Oui, mais pour ça il va te falloir attendre septembre si tout le monde tombe d'accord chose qui n'ai pas gagné.
As-tu essayé de regarder de ce côté ci Tinybutstrong ?
C'est un moteur de template très puissant et très leger, bonne soirée.
Ma petite contribution,
Dinoxyz
Hors ligne