Archive for the 'Coldfusion' Category

Globalisation et Coldfusion

Un CFC pour Coldfusion afin de globaliser une application en utilisant l’internationalisation de Java avec les Resource Bundles. Je suis parti du CFC de Paul Hastings pour charger les bundles et ensuite je me suis inspiré du code de BlogCFC pour le chargement dans l’application et pour le pointeur. Cet objet n’est pas finalisé mais peut être utilisé en production. Il prends en compte les performances et la gestion au mieux de la mémoire.

Télécharger : g11n CFC

Les méthodes pourraient être étendu pour charger des traductions depuis une base de données ou parser toute sorte de fichiers.

Utilisation

Ce fichier est dans dossier include qui se trouve à la racine du site root\include\org\g11n\g11n.cfc et est appelé dans le fichier application.cfm à la racine du site.

<cfif not isDefined("application.init") or (isDefined("url.reinit"))>
<cfset application.g11n=createObject("component","include.org.g11n.g11n").init()>
</cfset><cfset application.g11n.LoadResourceBundle(expandPath('/include/main'))>
</cfset><cfset application.g11n.addResourceBundle(expandPath('/p_dynamic/sites/main'))>
 </cfset><cfset application.g11n.utils=createObject("component","include.org.g11n.utils")> 
</cfset><cfset application.init = true>
</cfset></cfif>
 <cfset __ = application.g11n.utils.getResourceLocale>
</cfset>

Une seule instance de l’objet G11N est créé par application pour ne pas charger la mémoire et utiliser au mieux le cache d’une variable d’application. La variable application.init est utilisée pour réinitialiser les variables d’application en tapant un url du type http://moniste.com/monfichier?reinit

Les méthodes LoadResourceBundle et addResourceBundle parsent les différents bundles de langues et les stoquent dans des variables de type struct de l’objet G11N.

Cela se complique un peu avec le pointeur (ou alias) qui est utilisé pour simplifier l’écriture dans le code. fichier utils.cfc doit être éditer pour chaque application suivant l’instance de l’objet qui est créé et la variable de session ou est stoqué la langue.
Juste pour faire un pointeur tout en appelant la variable locale de l’object il faut passer par un objet ou une fonction itermédiaire (un “wrapper”) qui est ici dans utils.cfc Je ne trouve pas cela très élégant et rend l’organisation du code confus mais et très utile pour une simplication d’écriture. Le pointeur est créé par la ligne __ = application.g11n.utils.getResourceLocale dans l’application.cfm

<cfcomponent displayName="Utils" output="false">
           <cffunction name="getResourceLocale" access="public" returnType="string" output="false"
                hint="A utility wrapper for RB, to allow pointers / object application.g11n must be instantiate">
        <cfargument name="str" type="string" required="true">
            </cfargument><cfargument name="locale" type="string" default="#session.l#" required="false">
        <cfreturn application.g11n.getResource(arguments.str,arguments.locale)>
    </cfreturn></cfargument></cffunction>
</cfcomponent>

Donc maintenant que tout est instancié et pointé pour une simple localisation il vous suffit d’appeler la fonction qui pointe vers la méthode de l’objet.

<cfscript>
/* le pointeur à la variable de langue de la session par défaut #session.l# */
__("maclefdemonbundlealocaliser")
/* une clef a traduire avec une autre langue*/
__("maclefdemonbundlealocaliser","zh")
</cfscript>

Plusieurs remarques:

  • Les éditeurs de resources bundles ne sont pas trés courants. L’utilisation des resources bundles est laborieuse pour des non-codeurs. Je viens de travailler avec des traducteurs arabes/russe/chinois/espagnol, avec un export/import Excel je n’ai pas eu de remarques et cela a été efficace.
    Quelques liens utiles :
    Resource Bundle Editor en “standalone”
    Tranformer un Resource Bundle en fichier Excel en ligne de commande
    Un éditeur de Resource Bundle pour Eclipse
    Jinto, un autre éditeur de Resource Bundle pour Eclipse en mode tableaux
  • La mémorisation et l’utilisation de clefs n’est pas très pratique et demande plus d’attention au moment de coder.
  • Java semble bien gérer l’internationalisation. J’ai quelques problèmes avec la classe choiceFormat utile pour les pluriels. Je ne peux pas utiliser les méthodes ou instancier cet objet via Coldfusion.
  • Pointer une variable ou une méthode dans un objet n’est pas très intuitif avec CF
  • Je n’ai pas créé de pointeur pour la méthode messageformat mais cela reste possible.
  • La globalisation est importante mais Coldfusion n’offre rien de très utile pour cela au nivau de l’application il ya quelques fonctions de localisation. La mise en place et l’utilisation de ce CFC est laborieuse, mais une fois que cet objet est instancié avec un pointeur cela devient très simple.

CFFORUM, enfin un forum francophone pour Coldfusion !

Le travail communautaire c’est important. Comme des artisants nous avons besoins d’échanger nos bonnes pratiques ou nos outils. Pour Coldfusion la communauté francophone est très réduite. C’est pourtant un outil efficace mais payant. C’est peut être le prix qui à mis un frein à la diffusion de Colfusion. Quoi qu’il en soit vous pouvez trouver de nombreuses ressources, des astuces, poser des questions sur le forum www.Cfforum.eu de notre amis Serge Rapaille.

Xpath, recherche d’une valeur distincte

Si par une nuit d’automne vous cherchez à avoir les langues disponibles dans un fichier XML il faut bien sur penser à XPATH.
Imaginez ce fichier XML :

<document>
<title lang="en">My Title</title>
<title lang="fr">Mon titre</title>
<title lang="sp">Mi titulo</title></document>
<filename lang="fr">F1D60989-2A54-E4F1-8C54B87302968CAC.zip</filename>
<filename lang="en">F1D60999-2A54-E4F1-8A0B3600396F6522.pdf</filename>

Afin de récupérer les titres des langues spécifique il vous faut connaitre les langues disponibles.

<cfscript>
XMLsearch=XmlParse(XMLContent);
SearchTranslations=XmlSearch(XMLsearch, "//*[not(@LANG =preceding-sibling::*/@LANG)]/@LANG");
</cfscript>
<cfdump var="#SearchTranslations#" />

Ensuite il est possible de récupérer un élément suivant la langue, de faire une boucle par langue, à vous de voir. Attention ceci ne semble prendre de la ressource, ne pas utiliser avec des gros documents XML.

Références:
http://www.perfectxml.com/XPathDotNet.asp
http://www.w3schools.com/xpath/

IIS 6 sur un chemin réseau avec un “pool d’application”

Mais qu’est ce qu’il raconte ? Voici le problème, nous sommes lundi et comme tous les lundis vous voulez enregistrer des fichiers reçus via un formulaire web publié avec Coldfusion 7 sous IIS 6 vers un autre lecteur réseau sur un autre serveur dans la DMZ via le réseau. La phrase est un peu longue mais en prenant votre souffle ça va passer. On ne vous le dira jamais assez, lisez la documentation ! Euh oui merci mais la documentation en ligne vraiment je n’y comprends rien pourriez vous me répondre. Soit ! Je n’ai pas trés envie de vous faire un dessin.

  1. Créer d’un compte utilisateur sur les serveurs (serveur cible et serveur web) avec le même nom
  2. Partager le dossier de destination (serveur cible)
  3. Ajouter les droits en lecture/écriture à l’utilisateur créé précédemment dans les permissions du partage (serveur cible)
  4. Ajouter ce compte dans le groupe IIS_wpg (serveur web)
  5. Ajouter les droits en lecture/écriture l’utilisateur créé précédemment dans les permissions du dossier (serveur web)
  6. Créer un “application pool” (serveur web)
  7. Séléctionner l’identité créée précédemment pour l’application pool (serveur web)
  8. Changer les paramètres du dossier sur votre console IIS, créer une application, choisir l’application pool (serveur web)
  9. Ajouter les droits en lecture/écriture sur le dossier avec l’application au groupe IIS_wgp (serveur web)
  10. Ajouter les droits en lecture/écriture sur le dossier windows/temp/ au groupe IIS_wgp (serveur web)
  11. Vérifier bien les permissions sur les dossiers cibles

Il est maintenant possible avec un CFFILE d’enregistrer sur un serveur distant le fichier envoyé :

1
<cffile action="Upload" filefield="form.file" destination="\\serveurdistant\upload\" nameconflict="MakeUnique"></cffile>

Notes :

Accounts used for application pool identity should also be distinct from anonymous accounts and individual accounts for site authors and owners. Accounts used for anonymous access or for site authors and owners should not be added to the IIS_WPG group because doing so would grant those accounts access to directories that are shared among application pools such as the compression cache and ASP template cache.

Si vous configurez application pools avec une identity autre que Network_Service et que votre application utilise des scripts CGI, vous devez ajouter sur le compte local les droits suivant au compte de l’application avec Gpedit.msc :

  • Adjust memory quotas for a process (SeIncreaseQuota)
  • Replace a process at token level (SeAssignPrimaryToken)

Resources : IIS 6, Windows Server 2003 SP1, Coldfusion 7
Références :
www.microsoft.com/technet
rbazinet.wordpress.com
www.microsoft.com/technet

CFFILE, écrire un fichier en utf-8

Ecrire dans un fichier le contenu d’une variable en UTF-8 cela paraissait pourtant simple avec le tag CFFILE. Malgrés une lecture et une relecture de la documentation je ne trouve pas de solution. Je me retrouve avec un fichier html sans BOM et avec un mauvais encodage.

Et pourtant il est possible de spécifier l’encodage des caractères dans un CFFILE :

 <cffile action="write" file="myfile.html" output="#MyContent#" charset="utf-8"></cffile>

Toujours en se référent à la documentation nous pourrions aussi utiliser ceci :

 <cfprocessingdirective pageencoding="utf-8"></cfprocessingdirective>

Et enfin cela trouvé sur un blog pour les plus aventureux :

<cfscript>
function fileWriteUTF8(sFilePath, sInput){
	// declare jWrite object
	var jWriter = "";
	// create the file stream
	var jFile = createobject("java", "java.io.File").init(sFilePath);
	var jStream = createobject("java", "java.io.FileOutputStream").init(jFile);
	// output the UTF-8 BOM byte by byte directly to the stream
	jStream.write(239); // 0xEF
	jStream.write(187); // 0xBB
	jStream.write(191); // 0xBF
	// create the UTF-8 file writer and write the file contents
	jWriter = createobject("java", "java.io.OutputStreamWriter");
	jWriter.init(jStream, "UTF-8");
	jWriter.write(sInput);
	// flush the output, clean up and close
	jWriter.flush();
	jWriter.close();
	jStream.close();
</cfscript>

Resolu !
Version : Coldfusion 7.02
Références :
blog.pengoworks.com
www.niederhausen.net
livedocs.adobe.com
livedocs.adobe.com
fr.wikipedia.org




Commentaires récents