Alors, pourquoi j'ai nommé nom blog, "la tribu des mini pouces" ?
Tout commence lorsque ma femme m'a parlé d'une tribu mystérieuse en Corée, la "Tribu des mini pouces" ... J'ai alors pensé d'une tribu autochtone, qui avait la particularité d'avoir des petit pouces, afin de mieux visé à l'arc ...
Mais il n'en était rien ... en fait, ce sont les personnes championnes d'écriture de Texto sur portable ! (ce qui n'est certainement pas mon cas ... )

Apparament, il n'est pas rare de rencontrer des jeunes coréens taper des texto à la vitesse de la lumière ! Voici donc un petit hommage,a tous les Geeks et Geekettes, et surtout aux développeurs dont certains se reconnaitront dans cette tribu ... ^^

jeudi 4 août 2011

Le système de classe sous Extjs 4.0




pour la version 4.0, Extjs a bénéficié d'un grand travail de refactoring de toutes ses bibliothèques et d'être conforme aux nouvelles normes web, à savoir HTML 5 et CSS 3, et se base sur un nouveau système de classe. Cette nouvelle architecture est derrière presque toutes les classes écrite pour Extjs 4.X, et par conséquent, il est important de bien comporendre tout ce système avant de commencer à coder.



Ce tutoriel permet aux developpeurs de créer ou d'étendre les classes existantes de Extjs 4.x. Il est divisé en 4 sections:




  • Section I: "Aperçu" explique les besoins pour un système de classe robuste

  • Section II: "Convention de nommage" traite les bonnes pratiques de nommage des classes methods propriétés, variables et fichiers.

  • Section III: "Maitrise" Fournit des exemples détaillés de code étape par étape

  • Section IV: "Gestion des erreurs et deboggage" donne des conseil utiles sur comment les supprimer avec les exceptions



I. Apperçu



Extjs 4.0 est composé de plus de 300 classes et il est utilisé par une communauté de plus de 200 000 developpeurs à travers le monde avec chacun sa manière de coder. Le gros challenge est de fournir un socle commun d'une architecture du framework:



  • simple à appréhender et à le maitriser

  • rapide à développer, facile à debogguer, et rapide à déployer

  • bien organiser, extensible et maintenable



Javascript est un langage "orienté protopype", et non orienté objet comme c'est le cas pour PHP. Par sa nature, l'une de ses plus puissantes fonctionnalités est la FLEXIBILITE. Il peut en effet effectuer le même travail, mais de différentes manières, sur différents style de codage et de techniques. Sans une structure unifiée, un code javascript devient rapidement difficile à comprendre, maintenable et réutilisable.



La programmation basées sur les classes restent aujourd'hui le modèle le plus populaire auprès des développeurs. Les langages orientés objets exigent habituellement un très fort typage, doit fournir une encapsulation, et emploie des conventions standard de codage. La plupart des développeurs adhèrent à la plupart de ces principes, écrivent un code le plus prévisible possible, et le rends extensible et scalable le plus possible au fil du temps. Cependant, Ils(les langages Orienté Objets) ne possède pas les capacités dynamiques d'execution comme c'est le cas du Javascript.



Chaque approche à ses avantages et ses inconvénients, mais nous pouvons en tirer du meilleurs de ses 2 approche tout en masquant les inconvénients ? La réponse est oui et nous allons implémenter la solution sur Extjs 4.



II. Conventions de nommage



En utilisant les conventions de nommage au travers de votre code pour les classes, namespaces, et fichiers, vous aideront à garder votre code organisé, structuré, et lisible.



1) Les classes


Les nom des classes peuvent contenir uniquement des caractères alphanumériques. Les nombres sont autorisés mais déconseillés dans la plupart des cas, à moins qu'ils appartiennent à des termes techniques.ne pas utiliser les caractères underscore, tirets ou tout autre caractères non alphanumérique, par exemple:



  • MyCompany.useful_util.Debug_Toolbar est déconseillé

  • MyCompany.util.Base64 est acceptable



Les noms des classes doivent être regroupé dans des paquets proprement nommés en utilisant la notation "objet" du javascript, le point '.'. Au minimum, il devrait y avoir un unique espace de nom suivi par le nom de la classe. Par exemple:


MyCompany.data.CoolProxy

MyCompany.Application


Les nom des espace de haut niveau ainsi que les noms des classes doivent employer la notation Camel. Par exemple:



MyCompany.form.action.AutoLoad



Attention : Les classes qui ne sont pas distribué par Sencha, ne doivent jamais utiliser le nom d'espace de haut niveau "Ext".



Les acronymes doivent ainsi être suivi de la convention Camellisté comme ci dessous. Par exemple:




  • Ext.data.JsonProxy instead of Ext.data.JSONProxy

  • MyCompany.util.HtmlParser instead of MyCompary.parser.HTMLParser

  • MyCompany.server.Http instead of MyCompany.server.HTTP



2) Les fichier sources


Le nom des classes correspondent directement aux chemins du fichier dans lequel il y est enregistré. la conséquence est qu'il doit y avoir une seule classe par fichier. Par exemple:




  • Ext.util.Observable est placé dans chemin/de/la/source/Ext/util/Observable.js

  • Ext.form.action.Submit est enregistré dans chemin/de/la/source/Ext/form/action/Submit.js

  • MyCompany.chart.axis.Numeric est enregistré dans chemin/de/la/source/de/ma/societe/chart/axis/Numeric.js


chemin/de/la/source/ est le répertoire contenant les classes de votre application. Toutes les classes doivent rester à l'intérieure de ce répertoire commun et doit être proprement nommé pour la maintenabilité de votre application.



3) Methodes et Variables


De même que pour les noms de classes, les nom des méthodes et variables ne peuvent contenir uniquement des caractères alphanumériques. Les nombres sont aussi permis mais déconsillé dans la plupart des cas. Ne pas utiliser les underscores, les tirets, ainsi que les autres caractères non alphanumériques.



Le nom des méthodes et variables doivent toujours être sous le format Camel.
Par exemple:



Nom des méthodes accepté:
encodeUsingMd5(),
getHtml() contrairement à getHTML()
getJsonResponse() contrairement à getJSONResponse()
parseXmlContent() contrairement à ofparseXMLContent()


nom des variables accepté:
var isGoodName
var base64Encoder
var xmlReader
var httpServer



4) Propriétés


Les nom des propriétés d'une classe suivent exactement les même conventions que ceux des variables et des méthodes mentionné ci dessus, excepté des cas des constantes statiques. En effet, ces derniers doivent être toutes en majuscule, par exemple:



Ext.MessageBox.YES = "Yes"
Ext.MessageBox.NO = "No"
MyCompany.alien.Math.PI = "4.13"



III. La maîtrise



1. Declaration


1.1) A l'ancienne


Si auparavant vous avez utilisé les versions précédents de Extjs, vous êtes certainement familié avec la fonction Ext.extend pour créer une classe:


var MyWindow = Ext.extend(Object, { ... });



Cette approche est facilement facile à suivre pour créer une nouvelle classe qui hérite d'un autre. Autre que l'héritage direct, nous avions pas eu une API suffisament adaptée pour d'autres aspects de la création de classe tels que la configuration, les satiques les mixins. Nous reverrons tout cela en détail ultérieurement.



Laissez moi vous montrer un autre exemple:



My.cool.Window = Ext.extend(Ext.Window, { ... });



Dans cette exemple, nous voulons un espace nom(My.cool) pour notre nouvelle classe, et qui soit une extension de Ext.window.

In this example we want to namespace our new class, and make it extend from Ext.Window. Il y a là deux problématiques que nous devons traiter:



My.cool a besoin d'exister sous forme d'objet avant de lui assigner l'objet Window. Ext.Window a besoin d'exister/ chargé sur la page avant qu'il soit référencé. La première rpoclématique est résolu avec Ext.namespace, dont l'alias est Ext.ns. Cette méthode transverse récursivement à travers l'arbre de propriété/objet et le créée s'il n'existe pas encore. La partie ennuyeuse est que vous devez retenir les ajouts au dessus de Ext.extend tout le temps.



Ext.ns('My.cool');

My.cool.Window = Ext.extend(Ext.Window, { ... });


La deuxième problématique n'est pas facile à aborder parce Ext.Window peut être dépendant de plusieurs autres classes qui lui est directement/indirectement hérité, qui à son tour ses dépendances peuvent dépendre d'autres classes pour exister. Par cette raison, les application écrites sous les versions précédentes à Ext JS 4.0 devait usuellement inclure toute la librairie sous la forme de ext-all.js même si ils avaient besoin d'une toute petite portion du framework.



1.2) La nouvelle manière


Ext JS 4 a éliminé toutes ces inconvénients avec juste une méthode que vous avez besoin de retenir pour créer votre class: Ext.define. Sa syntaxe basique est défini de la manière suivante:



Ext.define(className, members , onClassCreated );


className: nom de la classe
members est un objet qui représente une collection de la classe membre dans ses paires clé/valeurs.
onClassCreated est une fonction optionnelle de rappel pour être invoquer lorsque toutes les dépendances de cette classe sont prêtes, et que la classe lui-même est pleinement créée. Du fait de sa nouvelle nature asynchrone de la classe de création, cette focntion de rappel peut être utilisé de plusieurs manières. Nous en discuteront dans la section IV.
Example:

Ext.define('My.sample.Person', {

name: 'Unknown',

constructor: function(name) {
if (name) {
this.name = name;
}

return this;
},

eat: function(foodType) {
alert(this.name + " is eating: " + foodType);

return this;
}
});

var aaron = Ext.create('My.sample.Person', 'Aaron');
aaron.eat("Salad"); // alert("Aaron is eating: Salad");


Notons que nous avons créé une nouvelle instance de My.sample.Person utilisant la méthode Ext.create(). Nous devrions utiliser le mot clé new (new My.sample.Person()). Cependant, il est recommandé de toujours prendre l'habitude d'utiliser Ext.create deouis qu'il vous permet d'avoir l'avantage d'avoir un chargement dynamique de classe.



2. La configuration


Sur Ext JS 4.0, nous introduisons une propriété de configuration qui est traité par le préprocesseur puissante Ext.Class avant que la classe ne soit créée. Les caractéristiques comprennent:



Les configuration sont complètements encapsulées depuis les autres classes membres.
Les méthodes getter et setter pour toutes les propriété de configuration sont automatiquement générées à l'intérieur de la classe prototype durant la création de la classe si la classe n'a pas ces méthodes déjà définies.



une méthode apply est ainsi générée pour toute propriété de configuration. Cette méthode setter auto générée appelle la méthode apply en interne avant de modifier une valeur d'une variable. Réécrire la méthode apply pour la propriété de configuration si vous avez besoin de personnaliser un process avant de modifier une variable. Si la méthode apply ne renvoie rien, alors la méthode setter ne modifie pas la valeur. pour exemple, voir, applayTitle en dessous.



Ext.define('My.own.Window', {

/** @readonly */
isWindow: true,

config: {
title: 'Title Here',

bottomBar: {
enabled: true,
height: 50,
resizable: false
}
},

constructor: function(config) {
this.initConfig(config);

return this;
},

applyTitle: function(title) {
if (!Ext.isString(title) || title.length === 0) {
alert('Error: Title must be a valid non-empty string');
}
else {
return title;
}
},

applyBottomBar: function(bottomBar) {
if (bottomBar && bottomBar.enabled) {
if (!this.bottomBar) {
return Ext.create('My.own.WindowBottomBar', bottomBar);
}
else {
this.bottomBar.setConfig(bottomBar);
}
}
}
});

Et ici, un exemplede comment il peut être utiliser

var myWindow = Ext.create('My.own.Window', {

title: 'Hello World',
bottomBar: {
height: 60
}
});

alert(myWindow.getTitle()); // alerts "Hello World"

myWindow.setTitle('Something New');

alert(myWindow.getTitle()); // alerts "Something New"

myWindow.setTitle(null); // alerts "Error: Title must be a valid non-empty string"

myWindow.setBottomBar({ height: 100 }); // Bottom bar's height is changed to 100



3. Les membres statiques


Les memebres statiques peuvent être défini en utilisant la configuration statique.

Ext.define('Computer', {

statics: {
instanceCount: 0,
factory: function(brand) {
// 'this' in static methods refer to the class itself
return new this({brand: brand});
}
},

config: {
brand: null
},

constructor: function(config) {
this.initConfig(config);

// the 'self' property of an instance refers to its class
this.self.instanceCount ++;

return this;
}
});

var dellComputer = Computer.factory('Dell');
var appleComputer = Computer.factory('Mac');

alert(appleComputer.getBrand()); // using the auto-generated getter to get the value of a config property. Alerts "Mac"

alert(Computer.instanceCount); // Alerts "2"



IV. Gestion d'erreur et débogage



Dans Ext JS 4, certains éléments pratiques peuvent vous aider à déboguer et gérer les erreurs.



Vous pouvez utiliser Ext.getDisplayName() pour afficher le nom d'une méthode. Cela est particulièrement pratique pour gérer les erreurs qui ont une description dans le nommage de classe et de méthode:



throw new Error('['+ Ext.getDisplayName(arguments.callee) +'] un message ici');


Lorsque une erreur est relevée dans une méthode d'une classe définie en utilisant Ext.define(), vous pourrez voir le nom de la méthode et de la classe dans la pile d'appel si vous utilisez les navigateurs qui utilisent le moteur WebKit (Chrome et Safari). Par exemple, voici ce qu'il pourrait être affiché dans Chrome:


jeudi 30 juin 2011

Ma première application Extjs 4.0


1. Recommandations


1.1 Navigateur Web


Extjs 4.0 supporte la plupart des navigateurs web connus, de IE 6 à la dernière version de Google Chrome. Nous recommandons cependant durant la période de développement d'application d'utiliser l'un des navigateurs suivant, pour leur outils de debbugging intégré:



  • Google Chrome 10+

  • Apple Safari 5+

  • Mozilla Firefox 4+, avec le plugin Firebug


Ce tutoriel suppose que vous employez la dernière version de Google Chrome. Si vous n'avez pas choisi Chrome, alors prenez un moment pour l'installer et familiarisez vous avec les outils de developpement de Chrome.


1.2 Le serveur Web


Même si il n'est pas obligatoire d'avoir un serveur Web pour faire fonctionner Extjs 4.0, il est hautement recommandé de développez avec un serveur, surtout depuis les restriction des navigateurs du protocole XHR en local. Si vous en avez pas, il est recommandez de télécharger un serveur HTTP Apache et de l'installer


Une fois que vous avez installé ou activé Apache, vous pouvez vérifier qu'il fonctionne avec l'adresse "localhost" dans votre navigateur. Vous devriez voir une page de démarrage indiquant que Apache HTTP Server a été installé avec succès et est en marche.



1.3. Ext JS 4 SDK


Téléchargez la Software Devloppment Kit ExtJs 4.0.Dézippez le fichier dans un nouveau répoertoire 'extjs' à l'intérieure du répertoire root du serveur. Si vous n'etes pas sur de la position de ce répertoire, veuillez consulter la documentation de votre serveur web.



Lorsque vous avez finit d'installer le serveur Apache, naviguez sur "http://localhost/extjs/index.html" de votre navigateur. Si la page de bienvenu de Extjs Js 4.0 apparait, alors vous avez réussit à tout configurer



2. Structure d'une application


2.1 Structure de base


Bien que cela ne soit pas obligatoire, il est préférable de prendre en compte toutes les suggestions listées ci dessous et de les considérées comme des conduites de bonnes pratiques pour la gestion, la maintenance, l'extensibilité et l'organisation de votre application. Il vous est recommandé de reprendre l'organisation structurelle de ExtJs des répertoires dans l'encadré suivant:



- appname    
- app
- namespace
- Class1.js
- Class2.js
- ...
- extjs
- resources
- css
- images
- ...
- app.js
- index.html


  • appname est un répertoire qui contient tous les fichiers sources de votre application

  • app contient toutes vos classes, le style de nommage des classes devrait suivre les conventions listées dans le guide des classes system

  • extjs contient les fichiers SDK de Ext JS 4

  • resources contient autant les CSS et images additionnels, responsables de l'apparence de l'application, que les autres ressources statiques(XML, JSON, etc...)
  • index.html est le point d'entrée du document HTML

  • app.js contient toute la logique de votre application


Ne vous focalisez pas sur la création de tous ces répertoires pour le moment, mais focalisons nous sur la production d'un minimum de code pour faire fonctionner une application ExtJs puis de l'executer. Pour cela, nous allons créer une simple application "Hello World" que l'on nommera "Hello Ext". Tout dabors, créons le repertoire suivant et les fichiers dans le repertoire root:


- helloext    
- app.js
- index.html

Alors dézipper la SDK de ExtJs 4.0 dans le repertoire nommé extjs dans le repertoire helloext



Typiquement, une application ExtJs est contenu dans un unique document HTML, index.html. Ouvrez le fichier index.html et insérez le code html suivant:



<html>
<head>
<title>Hello Ext</title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
<script type="text/javascript" src="extjs/ext-debug.js"></script>
<script type="text/javascript" src="app.js"></ script>
</head>
<body></body>
</html>



  • extjs/resources/css/ext-all.css contient toutes les feuilles de style pour faire fonctionner le framework

  • extjs/ext-debug.js contient le coeur du framework Extjs avec les libraires et les classes

  • app.js contiendra le code de votre application



Maintenant, vous etes prêt à écrire votre application. Ouvrez le fichier app.js et insérer le code javascript suivant:


Ext.application({   
name: 'HelloExt',
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
title: 'Hello Ext',
html : 'Hello! Welcome to Ext JS.'}
]
});
}});

Maintenant, ouvrez votre navigateur, et allez à "http://localhost/helloext/index.html". Vous devriez voir un Panel avec une barre de titre contenant le text "Hello Ext" et un message "Welcome" dans le corps du panel.



2.2 Chargement dynamique


Ouvrez l'outil de dev de Chrome et clickez sur la consile. Maintenant rafraichissez l'application Hello Ext. Vous devriez voir une alerte dans la console qui ressemble à cela:






Ext Js 4.0 est livré avec un système de chargement dynamique(que l'on nommera "Loader") permettant de récupérer les ressources javascript uniquement nécessaire pour le lancement de l'application. Dans notre exemple, Ext.create va créer une instance de Ext.container.Viewport. Lorsque Ext.create est appelé, le Loader va tout d'abord checker pour voir si Ext.container.Viewport a été défini. Si il n'est pas défini, alors le Loader va essayer de charger le fichier javascript qui contient le code de la classe Ext.container.Viewport avant d'instancier cet ledit objet. Dans notre exemple, le fichier Viewport.js va être charger avec succès mais le Loader détectera que les fichiers ont été chargées de manière moins optimale. Depuis que l'on a chargé uniquement le fichier viewport.js lorsque une instance de Ext.container.Viewport fut nécessaire, l'éxecution du code a été stoppé jusqu'à que le fichier a été chargé avec succès, provoquant un court retard. Ce retard serait aggravé si nous avions effectué plusieurs appels de Ext.create, parce que l'application attendrait pour chaque fichier à charger, avant de faire la demande de la prochaine requête.



Pour corriger cela, nous pouvons ajouter cette ligne de code avant l'appel de Ext.application



Ext.require('Ext.container.Viewport');


Cela permettra d'assurer que le fichier contenant le code Ext.container.Viewport est chargé avant que l'application ne s'execute. Voius ne devriez plus voir l'avertissement de Ext.Loader Lorsque vous rafraichisserez à nouveau la page.



2.3 Méthodes d'inclusion de la Librairie Extjs



Lorsque vous dezippez ExtJs 4.0, vous verrez les fichiers suivants:




  • 1.ext-debug.js - Ce fichier est à utiliser uniquement lors de la phase de développement. Il fournit le minimum des classes Ext Js core pour lui permettre de faire fonctionner normalement le Framework. Toute classe suplémentaire devra être chargé dynamiquement par des fichiers séparé comme il est montré ci dessous.


  • 2.ext.js - est identique à ext-debug.js mais minifié pour un usage de production. Cel signifie qu'il faudra l'utiliser en combinaison avec votre fichier d'application app-all.js. (voir section 3)


  • 3.ext-all-debug.js - Ce fichier contient toute la librairie ExtJS . Cela peut vous aider à améliorer votre apprentissage, cependant, ext-debug est préféré dans la plupart des cas pour un actuel developpement d'application.


  • 4.ext-all.js - C'est une version minifié du fichier ext-all-debug.js qui peut être employé dans un environnement de production. Cependant, il n'est pas recommandé car la plupart des applications n'utilise pas toute les classes qu'elle contient. Il est recommandé que you créez votre propre builder pour votre environnement de production qui sera décrite en section 3.




3. Déploiement


La SDK Sencha nouvellement introduite, rend le déploiement de toute application ExtJs 4.0 plus facile que jamais. Les outils vous permettront de générer un manifeste de toutes les dépendance javascript sous la forme d'un fichier JSB3 (format de ficheir JSBuilder), et créer un builder customizable contenant uniquement le code que votre application a besoin.



Une fois votre SDK installé, ouvrez un explorer et allez à votre répertoire de votre répertoire directement.



cd path/to/web/root/helloext


A partir de là, vous avez simplement besoin de lancer un ensemble de 2 commandes. Le premier génère un fichier JSB3:



sencha create jsb -a index.html -p app.jsb3


Pour les applications construites par des langages dynamiques telles que PHP, Ruby, ASP,..., Vous pouvez cimplement remplacer index.html par l'actuel URL de votre application:



sencha create jsb -a http://localhost/helloext/index.html -p app.jsb3


Cela scanne votre fichier index.html pour tous les framework et fichiers de votre application qui sont actuellement utilisé par votre application, et créée un fichier JSB appelé app.jsb3. Générant le fichier JSB3 pour la première fois, cela nous donne une chance de modifier le fichier app.jsb3 généré avant de le reconstruire. Cela peut vous aidé si vous avez des ressources personnalisée à copier,mais la plupart du temps, nous pouvons procéder à la construction de l'application par la seconde commande:



sencha build -p app.jsb3 -d .


Cela créée 2 fichiers basés sur le fichier jsb3:




1.all-classes.js - Ce fichier contient toutes les classes de votre application. Il n'est pas minifié, ainsi il est souvent utilisé pour débugger votre application construite. Dans ntore exemple, ce fichier est vide parce que notre application "Hello Ext" ne contient aucune classe.




2.app-all.js - Ce fichier est un fichier minifié de votre application avec toutes les classes requises pour le lancer. C'est une version de production du fichier all-classes.js avec app.js.



Une application Ext JS devra avoir une version index.html séparé pour une version de production de votre application. Vous aurez généralement besoin de l'utiliser pour contruire un process ou tester la logique côté serveur, mais pour l'instant, crééez uniquement un nouveau fichier dans le répertoire helloext et appeller index-prod.html:



<html>
<head>
<title>Hello Ext</title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
<script type="text/javascript" src="extjs/ext.js"></script>
<script type="text/javascript" src="app-all.js"></script>
</head>
<body></body>
</html>


Noté que ext-debug.jsa été remplacé par ext.js, et app.js a été remplacé par app-all.js. Si vous allez sur http://localhost/helloext/index-prod.html de votre navigateur, vous pourrez voir la version de production de votre application "Hello Ext".

lundi 20 juin 2011

Multi-application sous CodeIgniter

Bonjour à tous,

Un petit tuto pour faire plein d'application ou de site sous le même serveur ...
En général, il suffit de créer plusieurs répertoires, et de faire une simple redirection avec un fichier .htaccess.

Là, c'est à peut près la même chose sauf que l'on utilisera le même framework, CodeIgniter.

Lorsque vous dézipper CI_2.0.0, alors, vous obtenez les fichiers suivants:


Vous ouvrez le fichier index.php, et modifier les 2 valeurs suivantes:

$system_path = "../system";
$application_folder = "../application";


Vous mettez le fichier index.php dans le répertoire application

Enfin dans le htaccess, vous faites pointer dans le répertoire application/index.php !
pour créer une nouvelle application, il suffit de copier/coller le repertoire application, de renommer le repertoire et modifier la variable $application_folder !

Conseils:
- créer un repertoire doc dans la racine ou vous mettez le repertoire user_guide, je vous conseille egalement de mettre toute la doc de php, et des librairie que vous utilisez usuellement (librarie zend, sencha ...)
- dans le repertoire application, je vous conseille de créer un repertoire ressources (ou html), afin de mettre toutes les ressources utilisés dans le site web (image, video, css, ...)
- dans la racine créer un répertoire lib, ou vous mettrez toutes les libs que vous utilisez usuellement (zend, PEAR, ...)
- créer un projet vide, afin de le dupliquer rapidement sans les vues/controlleur... d'un autre projet

samedi 7 mai 2011

Optimisation d'une application mobile avec sencha




Bonjour à tous,

Après avoir fait un tuto sur comment customiser l'interface user d'une applicatiohttp://www.blogger.com/img/blank.gifn sencha grâce au SASS, je vous propose d'optimiser la librairies sencha en fonction de vos besoins.

I. INTRODUCTION


Alors pourquoi optimiser la librairie sencha ? Le fichier sencha-touch.js a un poids de 366 ko, minifié. C'est un très gros fichier que doit parser le navigateur, puis executer. Même si les navigateur sont de plus en plus important en terme de performance, cela n'est pas suffit pour traiter aussi rapidement un fichier de tel grandeur. De plus , ce gros fichier prends de la bande passante lors du téléchargement et ralenti le chargement de l'application, surtout lorsque l'utilisateur utilise la 3G.

Nous sommes dans la situation comparable aux années 80, lorsque les ordinateurs avait une capacité de mémoire limité obligeant les developpeur avec gérer de manière optimal la ram de l'ordinateur.

Si vous avez une petite application, alors vous pouvez gagner jusqu'à 20-25% du poids total du fichier sencha.

INSTALLATION


Dans le repertoire de votre librairie sencha, vous verrez le fichier sencha-touch.jsb3.
Copier ce fichier dans le même repertoire et renommer le [MON_APPLICATION].jsb3

A la fin de votre fichier, vers la ligne 278, vous verrez le code suivant:

"builds": [
{
"name": "Sencha Touch",
"target": "sencha-touch.js",
"debug": true,

Vous modifier le target en mettant "target": "[MON_APPLICATION].js",
Vous pouvez aussi modifier l'attribut name . ^^

Attention !
Faites attention à ce que Java run time soit installer car, jsbuilder utilisera une application ".jar".

Vous etes prêt maintenant pour votre première compilation de la librarie sencha !

MA PREMIERE COMPILATION DE LA LIBRAIRIE SENCHA


Ouvrez un shell windows en faisant "Executer >> cmd"

Positionner vous dans votre librarie Sencha puis dans le repertoire JSBuilder.

Ensuite, taper la commande:


JSBuilder.bat -d [REPERTOIRE DE SORTIE] -p [PATH_DU_FICHIER .jsb3]

si votre application se trouve dans c://sencha,
et que le resultat de votre compilation sera dans le repertoire racine,
alors vous aurez:


JSBuilder.bat -d c:/sencha -p c:/sencha/[MON8APPLICATION].jsb3


Dans votre console, vous devriez avoir :

Loading the Sencha Touch Project
Loaded 13 Packages
Loaded 1 Builds
* Parse sencha-touch-debug.js with options:
- minVersion: 1.1
- debug: true
* Compress and obfuscate sencha-touch-debug.js...
Copy resources...
Done building!


Vérifier bien que vos deux fichiers [MON_APPLICATION].js et [MON_APPLICATION]-debug.js soit présent dans le repertoire de sortie !

OPTIMISATION


Maintenant, ouvrez le fichier [MON_APPLICATION].jsb3 et trouvez les lignes de types:

{"path": "[PATH]", "name": "[FILE_NAME].js"},

supprimer un par un ces lignes, et compiler à chaque fois, puis tester votre application de manière à ce qu'il n y a pas de bug.
Répeter l'opération jusqu'à ce que vous arrivez à la fin du fichier.

CONCLUSION


Vous savez maintenant optimiser une application sencha que ce soit le css ou le fichier javascript. Vous avez fait un geste pour l'environnement, en économisant les ko superflus ! Et surtout votre application sera plus fluide.
Si vous optimisez aussi les images(3 ko par image), alors votre application sera vraiment concu pour les mobiles !

lundi 25 avril 2011

Utiliser SASS sur sencha touch pour personnaliser l'interface utilisateur




Bonsoir à tous,

Ce tutoriel va vous expliquer comment installer et utiliser SASS dans un projet Sencha Touch.

I. INTRODUCTION


Alors qu'est ce que Sencha Touch ? C'est un framework javascript, pour les application mobiles. Il se base sur HTML5 et CSS3 ! Et c'est d'ailleurs grâce au CSS3 , qu'il est aussi maniable au niveau de la customisation de l'interface utilisateur (user interface).

Maintenant, SASS ? C'est (en gros) une évolution du CSS3. En fait, sa puissance est de pouvoir créer des variables (bleu=#0000FF) et de pouvoir les appliquer à des endroits bien spécifiques sans devoir scanner tout le fichier css de base de Sencha Touch. Je vous invite de voir le site officiel

Il y a que SASS et sencha touch ? euh presque ... Je vous présente succintement Compass (ce 'est pas l'annuaire ), c'est le compilateur de SASS, en gros, c'est le programme pour passer de sass en css.

Et enfin, je présente encore Ruby on Rails ou Ror pour les intimes. C'est un framework, qui permet de faire des sites web et applications web, et il est dérivé du Python. (Je n'ai jamais réussi à maitriser ce langage, mais peut etre que un jour ...) Alors pourquoi ce Ror ? parce que pour utiliser SASS et et Compass, on a besoin de Ror ...

Pour tous ceux qui ont Windows, il sont dans le BON ENDROIT ! Nous allons apprendre à installer tous les composants un par un sur windows (pour les linuxien et mac-ien, débrouillez vous !), puis nous allons essayer de comprendre le fonctionnement de SASS.

II. INSTALLATION


1. Ruby on rails



Vous allez sur la page suivante : http://rubyinstaller.org/downloads/



puis télécharger le premier élément de RubyInstallers, et vous l'insallez sur votre ordinateur. Enfin vous suivez les instructions.

Après la fenêtre de bienvenu pour l'installtion de Ror, vous aurez 2 checkbox à cocher:
"add ruby executables to your PATH"
"associate rb ad rbw files with the ruby installation"

Installation des composantes de ruby


Lorsque l'installation de ruby est fini, vous allez dans la liste des programmes windows, puis allez dans le Ror que vous venez d'installer et lancer le shell de Ror. Le programme s'appelle :'start command prompt width ruby'

vous allez voir un shell.
pour vérifier que ruby est bien installer, vous faites:
ruby -v

et voir la version de ruby installer

puis, s'il n y a pas d'erreur, vous faites:
gem install haml
gem install haml-edge
gem install compass

et enfin
compass version

pour vérifier l'install de compass

Installation de Sencha Touch


Vous allez sur le lien au dessus et télécharger le fichier, puis vous le dézippez, dans le répertoire de projet que l'on va appeler [PROJET].

Vous ouvrez [projet]/examples/kitchensink/index.html avec chrome ou safari, et vous verrez l'application se lancer...

En faite nous allons utiliser cette application pour customiser l'interface utilisateur.



III. PROJET SASS



Dans le répertoire [PROJET]/examples/kitchensink/ressources , nous allons créer un répertoire sass.

config.rb


puis, créez un fichier config.rb dans ce nouveau répertoire.
Vous ouvrez ce fichier avec un éditeur de texte simple, et mettez le code suivant:
# Delineate the directory for our SASS/SCSS files (this directory)
sass_path = File.dirname(__FILE__)

# Delineate the CSS directory (under resources/css in this demo)
css_path = File.join(sass_path, "..", "css")

# Delinate the images directory
images_dir = File.join(sass_path, "..", "img")

# Load the sencha-touch framework
load File.join(sass_path, '..', '..', '..', '..', 'resources', 'themes')

# Specify the output style/environment
output_style = :compressed
environment = :production

Dans ce code Ror, on comprend que l'on ajoute des repertoires d'inclusion, et que cela se fait de la manière suivante:
"REP_A/REP_B/REP_C"
se transforme en
("REP_A","REP_B","REP_C")

le fichier config.rb permet de configurer Compass avant la compilation du sass.

application.scss


Vous créez dans le répertoire sass, le fichier application.scss qui va contenir 'le programme'.
Vous l'ouvrez avec un editeur de texte et mettez:

$body-bg-color: #fbf5e6;
$base-color: #efe1d0;
$active-color: #aa3030;

@import 'sencha-touch/default/all';
@include sencha-panel;
@include sencha-buttons;
@include sencha-sheet;
@include sencha-picker;
@include sencha-toolbar-forms;
@include sencha-tabs;
@include sencha-toolbar;
@include sencha-carousel;
@include sencha-indexbar;
@include sencha-list;
@include sencha-layout;
@include sencha-form;
@include sencha-sheet;

body {
font-family: Georgia;
color: #5a3d23;
}

.x-toolbar .x-toolbar-title {
color: #5a3d23;
}

Nous expliquerons le contenu de ce programme juste après ...
Vous sauvegarder tous les fichiers ouverts ...

Compilation


Avec votre command ruby de tot a l'heure, vous allez dans le répertoire SASS
[projet]/examples/kitchensink/ressources/sass

puis vous lancer la commande suivante:
compass compile

au bout de 20 sec, vous verrez dans le répertoire
[projet]/examples/kitchensink/ressources/css le fichier
application.css à côté de sink.css et codebox.css

vous ouvrez le fichier
[projet]/examples/kitchensink/index.html et désactiver la ligne
< link rel="stylesheet" href="resources/css/codebox.css" type="text/css">

pour la remplacer par
< link rel="stylesheet" href="resources/css/application.css" type="text/css">


Enfin, en visualisat, vous obtenez :


Fonctionnement du fichier .scss



Le fichier scss se compose de trois parties:
la première permet de réassigner de nouvelles valeurs à des variables
la deuxième permet d'importer tous les modules de sencha pour la compilation
la troisième parties de définir de nouvelles customisation et rêgles css voici un nouvel exemple:
// 1. Variable overrides, example:
$base-color: #af2584;

// 2. Include Sencha Touch styles
@import 'sencha-touch/default/all';
@include sencha-panel;
@include sencha-buttons;
@include sencha-sheet;
@include sencha-picker;
@include sencha-toolbar-forms;
@include sencha-tabs;
@include sencha-toolbar;
@include sencha-carousel;
@include sencha-indexbar;
@include sencha-list;
@include sencha-layout;
@include sencha-form;
@include sencha-loading-spinner;

// 3. Define custom styles (can use SASS/Compass), example:
.mybox {
@include border-radius(4px);
}

Si vous avez une petite application, vous avez la possibilité d'éliminer les package css que vous n'utilisez pas. Vous pourrez supprimer @include sencha-form; si s'il n y a pas de formulaire dans votre application. Bous pourrez éliminer jusqu'à 20% su poids du fichier CSS, ce qui représente une très bonne optimisation !

liste de toutes les variables configurable de sencha


$active-color
$alert-color
$base-color
$base-gradient
$bright-color
$button-gradient
$button-height
$button-radius
$button-stroke-weight
$carousel-indicator-size
$carousel-indicator-spacing
$carousel-track-size
$form-bg-color
$form-dark
$form-field-bg-color
$form-field-height
$form-fieldset-radius
$form-label-width
$form-light
$form-slider-size
$form-spacing
$form-textarea-height
$form-thumb-size
$form-thumb-space
$form-toggle-size
$global-row-height
$include-bottom-tabs
$include-button-uis
$include-default-icons
$include-default-uis
$include-form-sliders
$include-highlights
$include-html-style
$include-tabbar-uis
$include-toolbar-uis
$include-top-tabs
$light-tab-active
$light-tab-color
$page-bg-color
$sheet-bg-color
$sheet-button-spacing
$sheet-padding
$tabs-bottom-active-gradient
$tabs-bottom-icon-size
$tabs-bottom-gradient
$tabs-bottom-radius
$tabs-dark-active-color
$tabs-dark-color
$toolbar-gradient
$toolbar-highlights
$toolbar-icon-size
$toolbar-input-bg
$toolbar-input-color
$toolbar-input-height
$toolbar-spacing
$top-tab-height


Conclusion


Vous verrez, que customiser votre inrface deviendra un jeu d'enfant ... et en plus, ce tuto est valable aussi pour Extjs 4.0 !

Have fun !

jeudi 24 mars 2011

Livre sur le référencement



Bonsoir,

Je vous propose un livre sur le référencement. Pourquoi donc ?
L'une des problématique qui se pose pour toute personne qui créée des site ou application web, se pose la question de la visibilité de son site. In fine, cela amène à se poser la question du positionnement du site dans l'index du moteur de recherche.

A propos du livre



Référence Amazon du livre : Réussir son référencement web, de Olivier Andrieu

Si je vous parle de ce livre, c'est que au final, il m'a donné satisfaction. Il y a plus de 500 pages, et semble complet. Je n'ai pas encore fini de le lire, mais j'y ai appris beaucoup de chose.

Je ne sais pas si ce livre vous permettra de devenir u expert de la SEO, mais il pourra vous sensibilisé lors de vos développements des points qu'il faudra ne pas omettre. Par exemple, soigné les balises h1, title, le contenu ...

Ce que j'ai apprécié dans ce livre, ce sont les références et documentations qui sont nombreuses. L' auteur explique les raisons des mutations de l'algorithme d'indexation de google, le fonctionnement d'un moteur de recherche... Et il répond lorsque cela est possible à des interrogations concernant le référencement, sur des points précis: faut-il avoir plusieurs noms de domaine ? comment structurer une balises title ? ou faut il positionner les mots clés ? comment trouver des mots clés ...

Je suis pour l'instant à la page 180/ ~500, ce qui plutôt pas mal pour un deuxième jour de lecture.

Je finirais de faire ma critique lorsque j'aurais finit ce livre.

Utiliser un livre sur le référencement


Si vous avez développez des sites web (pour des amis,familles ou pour le travail), la première chose fut de maitriser le code html et le css. Puis, pour faire des site beaucoup plus élaborés, vous utilisiez le php ou jsp, ou asp, un langage permettat de générer des pages dynamiquement.
Puis après maitrisez le javascript, se pose la question du référencement. Même si j'avais des notions plus ou moins poussées (grâce aux forums spécialisé dans le référencement), je n'avais pas des certitudes exactes sur la manière dont fonctionnait les moteurs de recherche.

Ce qui est intéressant dans le domaine de la SEO, est de savoir que les moteurs de recherche ont eux même des objectifs et des contraintes (normale me direz vous...). Objectifs: vouloir intégrer un maximum de pages dans son index et du mieux possible. Contraintes: évitez de cacher le contenu, les fermes à liens ... Et dans cette problématique générale, se dégage un idéal pour les développeurs/ référenceures honnêtes à atteindre...
Le souhait de vouloir améliorer les sites webs que je gère me pousse au finale à me poser la question suivante: quel contenu je peux rajouter ? (la question peut vous sembler stupide, mais lorsque sur 50% des pages les informations essentielles se trouves sur le title, h1, et sur le contenu, il y a ici un manque cruel de contenu qu'il faut absolument combler ... )

La SEO semble être une science de marabout, ou il est difficile(pour ne pas dire impossible) de déterminer la prédiction du positionnement d'un site à un instant T. D'ailleurs à lire certains posts, on comprend qu'il y des superstitions(Google analyserait tel balise et pas celle là ...).
Mais de par les nombreux aspects que réunit le monde du référencement(les professionnels, pseudo professionnel, les amateurs, les marabouts ...), l'auteur recentre notre attention sur ce qui devient son leitmotiv : "ayez du bon contenu, de bonne qualité, et n'essayer pas de berner les moteurs de recherche"

Une notion que j'ai apprécié est le phénomène de la "longue traine": qui est une stratégie plus intéressante que le positionnement même du site sur certains mot clé. En effet, les internautes font des requêtes de plus en plus complexes, 5-8 mots, et plus du tout sur 1-2 mots, ce qui permet avoir de la visibilité de son site, sans devoir faire une stratégie de référencement agressive.

conclusion



Enfin, j'ai acheter ce livre, parce que
- un livre sera toujours mois chère qu'une formation sur le référecement
- les notions de référencement sont nécessaire pour la vie d'un dev web
- ce livre est gros, et comme google, j'aime le contenu... j'aime avoir réponse à toutes questions même s'elles sont stupides pour d'autre personnes.
- je dois trouver de futures axes de développement.

Nouveau site web : hayasaki.fr


Bonjour,

Absent depuis un petit moment, pour cause du lancement d'un nouveau site web :
www.hayasaki.fr

C'est le site de ma galerie qui se situe à Paris 4ième, dans les arts asiatiques et contemporaine.

Je vais vous parler de ce site, car c'est un laboratoire, je rajoute au fur et à mesure de nouvelles fonctionnalités.

Le site n est pas tout à fait terminer, mais le plus gros a été implémenté.
Voici quelques éléments techniques:
- html 1.0 strict
- validation W3C (à part le bouton twitter qui ne vient pas de moi)
- 4 langues(fr, en jp,kr)
- encodage utf-8
- framework codeigniter 2.0
- library Zend
- CSS 3
- générateur de sitemap
- générateur de mail d'invitation
- score pagespeed : 91/100
- score Yslow: 83/100
- webservice Google Map 3.0
- optimisation des images

Au pragramme:
- générateur de flux RSS
- CDN
- mise en place du cache
- minifier le css, js et html
- modification des urls

dimanche 13 février 2011

Gestion des pages Web sous CodeIgniter

Bonsoir à tous,

Je pense que c'est l'un des tutoriels les plus important de mon blog. Vous devriez gagner en rapidité de développement, car optimiser pour faire les tâche les plus importantes : création de contenu de la page et création de chaque composante de la page. De plus , nous gagnerons en visibilité car les contenus seront stockés dans le répertoire 'controllers' et les composantes dans le répertoire views. Tenez vous prêt, ce tuto est très très long ... Accrochez vous !

Je fais une première annonce, je bascule sur CodeIgniter 2.0. L'arborescence du projet ainsi qu'un certain nombre de fonctionnalités ont été modifié. Tous mes prochain posts prendront en compte ces changements.

Dans ce tutoriel, je souhaite vous montrer comment gérer de pages web, même complexes, dans le processus de création d'un site internet, qu'il soit petit, moyen ou grand...

La problématique aujourd'hui est que un nombre de plus en plus important de technologies s'ajoute au fur et à mesure(Rss, json, Ajax, Rest, Soap, Mail, Atom, Minify, Trackback, Css2/3, HTML4.1/4.4/5, etc ...), et il est de plus en plus difficile de de répondre de manière satisfaisante à ces technologies.

Nous allons structurer un projet web afin de ce concentrer sur l'essentiel, le CONTENU de la page !

Je vous conseille au préalable de lire cet article "Controller de controller", qui est un prérequis à cet article.

Présentation de répertoire controllers


La première chose à vous montrer est le répertoire 'controllers' comme le montre l'image ci dessous


Vous voyez 2 fichiers de configuration _config_html.ini.php et _config_mail.ini.php. Il permettent de configurer un ensemble de pages internet et l'autre configurer un ensemble de mail.

Les fichiers doctype_****.php sont en faire les formats de sorties d'une requête. simplement, si vous souhaitez renvoyer au client une page internet, alors vous utiliserez doctype_html.php. Si vous souhaitez renvoyer un flux RSS, et bien vous utiliserez le fichier doctype_rss.php...

Vous avez aussi le fichier controller.php. Ce fichier permet simplement d'implémenter des fonctionnalités qui peuvent être utiliser par toutes les pages. Cela peut être le cas de service de géolocalisation, WebServices Amazon, ou twitter ...etc... il sera pour l'instant 'vide'.

Enfin, les autres fichiers sont simplement les contrôleurs dans une architecture MVC.

Ficher _config_html.ini.php


Voici le contenu du fichier _config_html.ini.php :

;langue de la page en 2 lettres
lg = jp

;titre de la page
title = My website

;Encodage de la page
charset = UTF-8

;Favicon de la page
;true ou false
favicon = true

;adresse rss
rss =

;css & js
min_css = toto.css
min_js = titi.js

;cdn & host
cdn = cdn.toto.com
host = ceramique-paris.fr

;balises meta_
meta_description = coucou
meta_keywords =
meta_Author =
meta_Copyright =
meta_geo.region =
meta_geo.placename =
meta_geo.position =
meta_ICBM =
meta_DC.Title =
meta_DC.Creator =
meta_DC.Type =
meta_DC.Date =
meta_DC.Format =
meta_google-site-verification =

Vous voyez donc les paramètres de configuration d'une page internet(langue, encodage,balise meta,favicon ...). Si la variable est vide, alors elle ne s'affichera pas dans le code html. Vous pouvez déjà faire une configuration de base pour un ensemble de page internet, et créer une autre configuration pour un autre ensemble: (par exemple: créer un fichier _config_html_content.ini.php pour le contenu et _config_html_user.ini.php pour les pages utilisateurs)

fichier controller.php et doctype_html.php


Vous devez créer ces deux fichier et faire un copy-past sur votre projet.
Voici le fichier controller.php:

class Controller extends CI_Controller{

function __construct()
{
parent::__construct();
}

// Ajouter des fonctionnalité
/*
webservices ...
reporting
mail
*/

}


et ici, le fichier le fichier doctype_html.php

require_once 'controller.php';

class Doctype_html extends Controller{


/*
Attributs interne
*/
public $param = array();


/*
Constructeur
*/
function __construct($config_file="")
{
parent::__construct();

$this->param{'lg'} = 'fr';
$this->param{'title'} = 'Undefined title';
$this->param{'charset'} = 'UTF-8';
$this->param{'favicon'} = true;
$this->param{'js'} = array();
$this->param{'js_ext'} = array();
$this->param{'min_js'} = '';
$this->param{'css'} = array();
$this->param{'min_css'} = '';
$this->param{'rss'} = '';
$this->param{'cdn'} = '';
$this->param{'host'} = '';
$this->param{'meta'}{'description'} = '';
$this->param{'meta'}{'keywords'} = '';
$this->param{'meta'}{'Author'} = '';
$this->param{'meta'}{'Copyright '} = '';
$this->param{'meta'}{'geo.region'} = '';
$this->param{'meta'}{'geo.placename'} = '';
$this->param{'meta'}{'geo.position'} = '';
$this->param{'meta'}{'ICBM'} = '';
$this->param{'meta'}{'DC.Title'} = '';
$this->param{'meta'}{'DC.Creator'} = '';
$this->param{'meta'}{'DC.Type'} = '';
$this->param{'meta'}{'DC.Date'} = '';
$this->param{'meta'}{'DC.Format'} = '';
$this->param{'meta'}{'google-site-verification'} = ''; //google webmastertools
$this->param{'body'} = '';

if(!empty($config_file)){
$fichier = dirname(__FILE__)."/".$config_file;
$tableauIni = parse_ini_file($fichier);
foreach($tableauIni as $k=>$v){
$fn = '_'.$k;
$this->$fn($v);}
}
}

/*
__call
*/
public function __call($methode,$arg){

if($methode=='send')
$this->send();

// méthode ne commencant pas par '_' éliminé
if(substr($methode,0,1)!='_')
return false;

// balise meta
if(substr($methode,0,6)=='_meta_'){
$this->param{'meta'}{str_replace('_meta_','',$methode)} = $arg[0];
return true;
}

// existe dans param, modification de la valeur
if(isset($this->param{substr($methode,1,strlen($methode))}))
$this->param{substr($methode,1,strlen($methode))} = $arg[0];

return true;
}

/*
Envoi du code html
*/
public function send(){
// genere js ... todo

// genere css ... todo

// return code html
echo $this->load->view('tpl_html',$this->param);
}
}

Nous remarquerons que CI_Controller hérite Controller qui lui hérite doctype_html, qui lui héritera le controleur de notre page internet...

Voici le fichier tpl_html.php qu'il faudra mettre dans le répertoire views de votre projet. Ce fichier récupéra les valeurs du fichier _config_html.ini.php, et les utilisera pour générer le code html.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo !empty($lg) ? $lg:'fr';?>" lang="<?php echo !empty($lg) ? $lg:'fr';?>" >
<head>
<meta http-equiv="content-type" content="text/html; charset=<?php echo isset($charset) ? $charset:'UTF-8';?>" />
<title><?php echo !empty($title) ? $title:'Undefined title !';?></title>
<?php if(!empty($meta{'description'})):?><meta name="description" content="<?php echo $meta{'description'};?>" />
<?php endif;?>
<?php if(!empty($meta{'keywords'})):?><meta name="keywords" content="<?php echo $meta{'keywords'};?>" />
<?php endif;?>
<?php if(!empty($meta{'geo.region'})):?><meta name="geo.region" content="<?php echo $meta{'geo.region'};?>" />
<?php endif;?>
<?php if(!empty($meta{'geo.placename'})):?><meta name="geo.placename" content="<?php echo $meta{'geo.placename'};?>" />
<?php endif;?>
<?php if(!empty($meta{'geo.position'})):?><meta name="geo.position" content="<?php echo $meta{'geo.position'};?>" />
<?php endif;?>
<?php if(!empty($meta{'ICBM'})):?><meta name="ICBM" content="<?php echo $meta{'ICBM'};?>" />
<?php endif;?>
<?php if(!empty($meta{'DC.Title'})):?><meta name="DC.Title" content="<?php echo $meta{'DC.Title'};?>" />
<?php endif;?>
<?php if(!empty($meta{'DC.Creator'})):?><meta name="DC.Creator" content="<?php echo $meta{'DC.Creator'};?>" />
<?php endif;?>
<?php if(!empty($meta{'DC.Type'})):?><meta name="DC.Type" content="<?php echo $meta{'DC.Type'};?>" />
<?php endif;?>
<?php if(!empty($meta{'DC.Date'})):?><meta name="DC.Date" content="<?php echo $meta{'DC.Date'};?>" />
<?php endif;?>
<?php if(!empty($meta{'DC.Format'})):?><meta name="DC.Format" content="<?php echo $meta{'DC.Format'};?>" />
<?php endif;?>
<?php if(!empty($meta{'google-site-verification'})):?><meta name="google-site-verification" content="<?php echo $meta{'google-site-verification'};?>" />
<?php endif;?>
<?php if(!empty($min_css)):?><link href="<?php echo !empty($cdn) ? 'http://'.$cdn.'/'.$min_css:'http://'.$host.'/'.$min_css;?>" rel="stylesheet" type="text/css" />
<?php endif;?>
<?php if(!empty($js_ext)):foreach($js_ext as $v){?><script type="text/JavaScript" src="<?php echo $v;?>"></script>
<?php }?>
<?php endif;?>
<?php if(!empty($min_js)):?><script type="text/JavaScript" src="<?php echo !empty($cdn) ? 'http://'.$cdn.'/'.$min_js:'http://'.$host.'/'.$min_js;?>"></script>
<?php endif;?>
<?php if($favicon==true):?><link rel="icon" type="image/png" href="<?php echo !empty($cdn) ? 'http://'.$cdn.'/favicon.ico':'http://'.$host.'/favicon.ico';?>" />
<?php endif;?>
</head>
<body>
<?php echo $body;?>
</body>
</html>


Création de votre page monTest/index/


Il faut créer le fichier monTest.php dans le répertoire controllers, et mettre le code suivant

require_once 'doctype_html.php';

class MonTest extends Doctype_html{

function __construct(){
parent::__construct('_config_html.ini.php');
}



public function index(){
//print_r($this->param);
$this->send();

}
}

Vous comprendrez que dans le code précédent, on charge le fichier de configuration '_config_html.ini.php' dans le constructeur du contrôleur monTest qui est hérité de Doctype_html.
Dans la fonction index, vous pourrez visualisez les valeurs des variables de la page, grâce à print_r($this->param);.
De plus, si vous allez dans la page http://localhost/[APP]/monTest/index/, vous verrez une page blanche (parce qu'il n ' a pas de contenu), mais, via firebug, vous aurez le code html suivant:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="jp" >
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>My website</title>
<meta name="description" content="coucou" />
<link href="http://cdn.toto.com/toto.css" rel="stylesheet" type="text/css" />
<script type="text/JavaScript" src="http://cdn.toto.com/titi.js"></script>
<link rel="icon" type="image/png" href="http://cdn.toto.com/favicon.ico" />
</head>
<body>
</body>
</html>

Vous voyez le titre de la page My website.

Modifier les variables dynamiquement


Question, allons nous créer un fichier _config_html.ini.php par page ? et bien non, ce n'est pas obligatoire, et cela est même déconseillé pour du très grand contenu (milliers de pages ^^).
En fait il est possible de modifier tous les valeurs de ces variables dynamiquement, nous allons modifier le title de la page avec le code suivant, à mettre dans la fonction index():

$this->_title('nouveau titre');
$this->send();

Vous devriez voir dans la balise title :'nouveau titre'.
En fait, vous précédez le nom de la variable par le caractère underscore. donc pour le title, faire:
$this->_title('[TITLE]');


pour la langue, faire:
$this->_lg('[LANGUE]');


, pas compliqué ... non ?
et pour le contenu, c'est :
$this->_body('[CONTENU]');

A priori, vous n'aurez pas besoin d'utiliser la variable body dans la méthode index(), nous verrons pourquoi dans la section suivante ...

Pour faire un récap des possibilités de manipulation, d'abord vous charger le fichier de configuration de votre page internet, puis si des paramètres ne vous plaisent pas, comme le titre de la page, vous la modifiez à la volé ! C'est la classe, non ?

Composants d'une page internet


Il y a une chose que nous avons oublié est qu'une page internet est composé d'éléments qui sont placé au même endroit: header en haut, footer en bas, menu à gauche ou sous le header ...

Pour faire simple, nous allons créer une structure simplifié :
header/menu/contenu/extra/footer superposé les uns sur les autres.
extra, situé entre contenu et footer s'affichera uniquement pour la page monTest/index, et non pas sur une autre page.

dans le répertoire views, nous allons 5 fichiers:
gb_content.php:
<div style="border:1px solid blue;margin: 5px;padding :5px;color:blue;"><h2><?php echo $content;?></h2></div>


gb_extra.php:

<?php echo$_SERVER{'REQUEST_URI'};if($_SERVER{'REQUEST_URI'}=='/bimpoo/monTest/index.html'){?><div style="border:1px solid green;margin: 5px;padding: 5px;color:green;"><h2>EXTRA</h2></div><?php }?>


gb_footer.php:

<div style="border:1px solid red;margin: 5px;padding :5px;color:red;"><h2>FOOTER</h2></div>


gb_header.php:

<div style="border:1px solid red;margin :5px;padding :5px;color:red;"><h2>HEADER</h2></div>


gb_menu.php:

<div style="border:1px solid red;margin :5px;padding: 5px;color:red;"><h2>MENU</h2></div>


Nous allons remplacer la méthode index par la suivante:


public function index(){
$this->param{'content'} = 'COUCOU !';
$this->send();
}

Nous ajoutons la variable content qui sera le contenu de la page internet, puis nous appelons la focntion send pour générer la page internet et la renvoyer. Nous allons créer une méthode similaire index2() avec le même contenu que index(). Si nous générons la page monTest/index, il n y aura toujours qui s'affichera car on n' a pas encore chargé les vus... !

pour cela, il faut ouvrir le fichier doctype_html.php et aller à la méthode send()
sur le fichier, il y avait juste:

echo $this->load->view('tpl_html',$this->param);


C'est avant cette ligne de code que nous allons rajouter toutes les autres vues, avec le code suivant:

$html = $this->load->view('gb_header',$this->param,true);
$html .= $this->load->view('gb_menu',$this->param,true);
$html .= $this->load->view('gb_content',$this->param,true);
$html .= $this->load->view('gb_extra',$this->param,true);
$html .= $this->load->view('gb_footer',$this->param,true);
$this->_body($html);
echo $this->load->view('tpl_html',$this->param);

nous chargeons toutes les vues dans la variable $html que nous mettons ensuite dans la variable body ! puis nous générons la page internet.
C'est donc ici que vous allez imposer une structure (ou plusieurs structure si vous répliquez le fonction send()) d'une page internet !
N'oubliez que chaque vu se gérée d'elle même, dans le but de simplifier le traitement du contrôleur et de lui dédier uniquement le contenu principale de la page : par exemple pour activer l'onglet d'un menu en fonction de l'url, il vous suffit de rajouter une variable dans $this->param (par exemple $this->param{'onglet_actif'}) et lui attribuer le nom du contrôleur.

$this->param{'onglet_actif'} = __method__;

ensuite, vous le récupérez dans la vue et faire le traitement adéquate ...

voici le résultat de la page monTest/index :







Et la, le résultat de la page monTest/index2

Si vous avez remarquez le code dans le fichier gb_extra, le code html est entouré de balises php. Ces balisent testent pour savoir si l'url est celle de monTest/index ou pas. Si c'est oui, alors le code html est affiché !

Conclusion


J'espère que vous aurez compris l'intérêt de ce tutoriel : Vous faire gagner du temps et rendre le projet facile à maintenir !
Voilà, si vous êtes arrivé là, alors vous etiez un vrai warior ! N'hésitez pas à me contacter pour plus d'info ou pour des corrections !

vendredi 14 janvier 2011

Faire une table html en 4 lignes de code !

Introduction


Humm ... je vous vois très sceptique sur le titre de ce nouveau tuto ! Mais vous allez voir que c'est vrai ... hihihi ...
Par contre ce que je n'ai pas dit, c'est que nous allons créer une table html à partir des données d'une table mysql !

Un tableau simple


On va créer un contrôleur test_table ... et mettre le code suivant

class test_table extends Controller{

public function test(){

$this->load->database();
$this->load->library('table');
$query = 'SELECT * FROM [TABLE] LIMIT 0,10';
echo $this->table->generate($query);
}
}

Vous affichez le contenu d'une table mysql. Vous pouvez choisir les colonnes que vous souhaitez afficher en remplaçant l'étoile par les noms des colonnes, comme on le fait pour une requête mysql...

Modifier l'intitulé de la colonne


Parfois l'intitulé ne correspond pas à ce que vous souhaitez afficher ou même pire, il n'a pas forcément de sens explicite. C'est la raison pour laquelle, il serait préférable de changer l'intitulé.
Pour cela, rien de plus simple, à côté de chaque nom de colonne, on rajoute "AS [nouvel intitulé]" dans la requête...
Par exemple, si on a comme requête:
SELECT nom,prenom,add,tel FROM user LIMIT 0,10

on mettra:
SELECT 
nom AS 'Nom de famille',
prenom AS 'Prénom',
add as 'Adresse de domicile',
tel AS 'Téléphone fixe de la maison'
FROM user LIMIT 0,10


Voila, vous suivez ... ?

Nouvelle mise en page...


Plus compliqué, on va faire un tableau à 2 colonnes. La première colonne concernera les informations de l'utilisateur(nom, prénom, adresse), et le second son statut (connecté, non connecté)...
tout en utilisant un template spécifique ...
alors ... ?
Bon, tout d'abord, on va faire ce que nous savons faire ... c'est à dire la deuxième colonne:on aura donc :

SELECT [UN TRUC] AS Utilisateur, 
statut AS 'Statut de l\'utilisateur'
FROM user LIMIT 0,10

Maintenant, il faut remplacer [UN TRUC] parle code que l'on souhaite ajouter...
le template sera de la forme suivante :
<b>Nom</b> : [nom]<br />
<b>Prénom</b> : [prenom]<br />
<b>Adresse</b> : [adresse]
En fait, on utilisera la fonction CONCAT de mysql ! de la manière suivante :


CONCAT('<b>Nom</b> : ',nom,
'<br/><b>Prénom</b> : ',prenom,
'<br /><b>Adresse</b> : ',adresse)


on a donc au final la requête suivante :
SELECT CONCAT(
'<b>Nom</b> : ',nom,
'<br/><b>Prénom</b> : ',prenom,
'<br /><b>Adresse</b> : ',adresse) AS Utilisateur,
statut AS 'Statut de l\'utilisateur'
FROM user LIMIT 0,10


Conclusion


Voilà, nous pouvons faire des tableaux plus agréable à voir et surtout nous avons des possibilités importantes de présentation !
Je vous revois à la documentation de codeIgniter pour customiser encore plus vos tableaux ...
Mais vous pouvez déjà voir que l'on peut créer des tables avec du code concis ...

Un controlleur de controlleur ...

Qu'est ce que c'est ce titre ???


Alors, le but de ce tutoriel est de proposer une petite astuce qui bien pensé améliora votre développement web sous codeIgniter ... Pour comprendre ou je veux en venir, on va passer tout de suite à un exemple, sous forme de problématique simple et usuelle que vous pourrez réemployer pour d'autre cas divers et variés...

Problématique ...


Le contrôleur est le "chef d'orchestre" lorsqu'une requête arrive au serveur. Il va trouver les éléments à afficher, se connecter à la base de données, mettre en forme le contenu, puis envoyer le tout au client ...
Lorsque le contrôleur doit générer une page internet, alors, pour certaines parties de la page, il génèrera toujours le même code html (comme c'est le cas pour le header, footer, ou le menu ...), et certaines parties changent en fonction de la requête, comme c'est le cas du contenu par exemple.
Nous allons donc faire en sorte que chaque partie ai un code html par défaut et, que l'on puisse modifier n'importe quelle partie en fonction de la page demandée. Nous allons faire une page "Erreur 404", puis nous allons faire en sorte que l'on puisse transformer en une autre page ...

Le contrôleur de la page 404


Il faut créer un fichier main_controlleur.php dans le répertoire [MYAPP]/system/controllers
et vous mettez le code suivant:
class main_controller extends Controller{

public function _header(){
echo '<h1>HEADER</h1>';
}

public function _footer(){
echo '<h1>FOOTER</h1>';
}

public function _content(){
echo '<h1>PAGE 404</h1>';

}

public function _process(){
$this->_header();
$this->_content();
$this->_footer();
}
}

Vous avez 4 fonctions privées. Les trois premières servent à générer une partie du code html (header, contenu de la page 404, et footer).
Et la dernière sert à générer la page, en appelant les autres fonctions privées.
Aucune méthode de se contrôleur ne peut être appelé directement puisque toutes les méthodes sont privées, ce qui nous arrange.

nous allons maintenant créer un nouveau contrôleur "crtl_test", qui lui sera accessible et qui sera la classe fille de main_controller. Il faut donc créer le fichier crtl_test.php et mettre le code suivant:

require_once APPPATH.'controllers/main_controller.php';

class crtl_test extends main_controller{

function test(){
$this->_process();
}

}

Si vous appelez la page [HOST]/crtl_test/test.php, alors vous verrez:
HEADER
PAGE 404
FOOTER

Maintenant, on va redéclarer la fonction privée _content dans la classe crtl_test, on a alors au finale:

require_once APPPATH.'controllers/main_controller.php';

class crtl_test extends main_controller{

public function _content(){
echo '<h1>AUTRE PAGE ...</h1>';
}

function test(){
$this->_process();
}
}

Vous verrez, si vous appelez la même page, vous aurez le contenu qui changera ...c'est à dire:
HEADER
AUTRE PAGE ...
FOOTER

Ensuite ...


Vous faites dérivez tous les contrôleurs que vous créerez à main_controller, afin qui jouissent automatiquement des mêmes fonctions par défaut. Vous devriez aller bcp plus vite dans le développement et surtout la maintenance y sera facilité ... !

Dans vos futures développements


Pensez à toujours créer un "controleur de controleur" (même si le main_controller est vide), car pour factoriser le code facilement, vous allez devoir migrer certaines fonctions de crtl_test vers main_controller.