Changement des URL de type suous-domaine à type sans sous-domaine

Aujourd’hui je m’occupe de réécrire les URL du site pour passer d’un format de réécriture en sous domaine vers un format dossier.
Ancien URL rewrite:

http://CATEGORIE_1.domaine.com

Nouveau format:

http://domaine.com/CATEGORIE-1

Suite à quelque recherches sur le net il semblerait que le premier format pose quelque soucis au référencement:
1) L’utilisation d’un sous domaine est mois performante que le format sans sous-domaine car cela est interprété comme étant dehors du domaine principale. Ce problème est visible à l’utilisation d’un compte webmaster chez google.
IL est de bonne pratique de choisir un format unique pour toutes les pages du site: avec www ou sans www.
Dans le cas d’un réécriture en sous domaine nous sommes obligés à utiliser une wildcard (*) dans nos DNS pour pouvoir faire marcher correctement ce type d’URL. Cela complique donc la redirection vers un format avec www.
2) Underscore ou trait d’union? Dans ce cas aussi il semblerait que le underscore n’est pas interprété comme étant un espace. L’URL sera donc mois performant au recherches.

Voici la méthode que j’ai utilisé pour changer les URL et rediriger en 301 les anciens:

Dans mon htaccess:

RewriteRule ^(..)/(.*) /%1/$1/$2 [R=301,L]
RewriteRule ^(..)/(.*) redirect301.php?sousdom=%1&var1=$1&var2=$2 [QSA,L]

Dans mon php:

$newurl=str_replace(« _ », »- »,$_GET["sousdom"]). »/ ».$_GET["var1"]. »/ ».$_GET["var2"];
header(‘HTTP/1.1 301 Moved Permanently’, false, 301);
header(‘Location: http://www.domaine.com/’.$newurl);
exit();

Leave a Comment

Création d’un Download Manager avec adobe AIR

J’ai longtemps cherché sur Internet sans succès  une utilitaire  prêt à l’emploi pour télécharger  plusieurs fichiers depuis un serveur.
J’ai enfin décidé de créer moi même un petit script en utilisant Flash(as3) et Adobe AIR.
Voici le projet terminé:

Avant de commencer il vous faut d’abord installer l’extension Adobe AIR pour votre Flash:
http://www.adobe.com/products/air/develop/flash/
Une fois installé, vous auriez la possibilité de configurer et créer votre application AIR depuis Flash.

j’ai commencé pour créer un nouveau fichier flash (dwnmngr.fla) et choisi dans les options de publication l’option « AIR 1.5″ (c’est actuellement ma version de AIR).
air dans flah

Il faut ensuite créer un clip qui vas composer la liste des fichiers à télécharger.
J’ai apellé ce clip ‘itemfile’ et coché la case « exporter pour action script ».
itemfile

Le clip est composé d’un une barre noire qui fait de background et un champ text dynamique dont le nom de variable est « flabel ».
J’ai créé un clip pour le bouton de lancement du téléchargement des fichiers (exporté en action script sous le nom « BT »).

Pour le développement des classes j’ai d’abord structuré l’architecture des dossiers qui vont contenir toutes mes fichier .as, ainsi:

- as3/ : dossier racine des classes
- as3/com/ : ici les classes d’interaction avec les données à distance sur le serveur remote (le serveur qui héberge les fichiers à télécharger)
- as3/layout/: ici les classes pour gérer l’affichage de différents clips qui composent le downloadmanager
- as3/fsystem/ : ici les classes pour lire et enregistrer les fichiers downloadés (interaction avec le FileSystem de l’utilisateur)

J’ai ensuite défini dans les proprietés avancés de « actionscript3″ la classe Main du downloadmanager ainsi que le dossier qui contiens toutes les autres classes:
parametresavances

Pour cet version de test j’ai créer à la racine de mon projet (la où il y a mon fichier dwnmngr.fla) un dossier « datas/ » qui contient un fichier XML (fileslist.xml) avec la liste des fichiers à downloader.

/datas/fileslist.xml:

<?xml version='1.0' encoding='utf-8'?>

  <fileslist>

  <fileitem>

  <file_label><![CDATA[Image 1]]></file_label>

  <file_path><![CDATA[http://dartea.com/wp-content/uploads/2010/01/1.jpg]]></file_path>

  <file_name><![CDATA[image1.jpg]]></file_name>

  </fileitem>

<fileitem>

  <file_label><![CDATA[Image 2]]></file_label>

  <file_path><![CDATA[http://dartea.com/wp-content/uploads/2009/12/2.jpg]]></file_path>

  <file_name><![CDATA[image2.jpg]]></file_name>

  </fileitem>

<fileitem>

  <file_label><![CDATA[Image 3]]></file_label>

  <file_path><![CDATA[http://dartea.com/wp-content/uploads/2009/12/3.jpg]]></file_path>

  <file_name><![CDATA[image3.jpg]]></file_name>

  </fileitem>

</fileslist>

Pour lire le fichier XML avec la liste des fichiers à télécharger j’ai commencé par créer un classe dans as3/com/ qui s’appelle « XMLFilesList » dans le fichier XMLFilesList.as.
Cette classe et très simple, il parse le fichier XML et crée un objet XML avec l’ensemble des données. Quand le travaille de cette classe est terminé elle réenvoi l’evenement « FILESLIST_ENDJOB »:

/as3/com/XMLFilesList.as :

package com

  { 

  import flash.display.MovieClip;

  import flash.events.*;

  import flash.net.*;

  public class XMLFilesList extends MovieClip

  {

  public var  FilesListing:XML;

 public function XMLFilesList():void{

  var RequestXML:URLRequest = new URLRequest("datas/fileslist.xml");

  var LoaderXML:URLLoader = new URLLoader();

  LoaderXML.dataFormat=URLLoaderDataFormat.TEXT; 

  LoaderXML.addEventListener(Event.COMPLETE, XMLLoadSuccessful);

  LoaderXML.addEventListener(IOErrorEvent.IO_ERROR, XMLLoadError); 

  LoaderXML.load(RequestXML);

  }

  private function XMLLoadSuccessful(evt:Event):void{

  FilesListing=new XML(evt.target.data); 

  this.dispatchEvent(new Event("FILESLIST_ENDJOB"));

  }

  private function XMLLoadError(evt:Event):void{

  this.dispatchEvent(evt);

  }

  }

  }

Pour afficher la liste des fichiers à télécharger j’ai créé une classe dans as3/layout/ qui s’appelle « FileListPanel » dans le fichier FileListPanel.as.
Cette classe nécessite comme argument dans le constructeur l’objet XML avec les données (créé par la classe « XMLFilesList « ).
Une fois que l’utilisateur clique sur le bouton « download » un évènement « START_DOWNLOAD » est produit.

/as3/layout/FileListPanel.as :

package layout
{

	import flash.display.*;
 	import flash.events.*;

    public class FileListPanel extends MovieClip
    {

		private var Item:MovieClip;
		private var XMLData:XML;
		private var BTDownload:MovieClip;
		public var DownloadQueue:Array;

		public function FileListPanel(_XMLData):void{
				 XMLData=_XMLData;
				 DownloadQueue=new Array();
				 var startpos:Number=0;
				 var cnt=0;
				 for(var i:String in XMLData..fileitem) {

					  Item=new Itemfile();
					  Item.y=startpos;
					  Item.flabel.text=XMLData.fileitem[i].file_label;
					  Item.fname=XMLData.fileitem[i].file_name;
					  Item.fpath=XMLData.fileitem[i].file_path;
					  startpos+=27;
					  addChildAt(Item,int(i));

					  DownloadQueue[cnt]=[XMLData.fileitem[i].file_name,XMLData.fileitem[i].file_path];

					  cnt++;

				}

				BTDownload=new BT();
				BTDownload.x=200;
				BTDownload.y=startpos+50;
				BTDownload.addEventListener(MouseEvent.CLICK,Download);
				addChild(BTDownload);		

		}

		private function Download(evt:MouseEvent){
			this.dispatchEvent(new Event("START_DOWNLOAD"));
		}

	}
}

Pour gérer la liste des fichiers à télécharger, j’ai créé la classe Downloader dans /as3/fsystem/Downloader.as, c’est le cœur de l’application.

package fsystem

  {

  import flash.display.MovieClip;

  import flash.net.*;

  import flash.events.*;

  public class Downloader extends MovieClip

  {

  private var I:Number;

  private var DownloadList:Array;

  private var FileSystemObj:Object;

  private  var loader:URLLoader

  public function Downloader(DownloadQueue,AIRFsystem){

  I=0;

  DownloadList=DownloadQueue;

  FileSystemObj=AIRFsystem;

  loader= new URLLoader();

  loader.dataFormat = URLLoaderDataFormat.BINARY; 

  configureListeners();

  GetRemoteFile();

  }

  function GetRemoteFile(){

  var request = new URLRequest(DownloadList[I][1]);

  try {

  loader.load(request);

  } catch (error) {

  trace("Unable to load requested document. ["+DownloadList[I][1]+"]");

  }

  }

  function configureListeners() {

  loader.addEventListener(Event.COMPLETE, completeHandler);

  loader.addEventListener(Event.OPEN, openHandler);

  loader.addEventListener(ProgressEvent.PROGRESS, progressHandler);

  loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);

  loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);

  loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

  }

  function completeHandler(event) {

  var loader = URLLoader(event.target);

  //trace("Lecture du fichier remote terminé!");

  var abspath=FileSystemObj.DefaultFilesDir+"/"+DownloadList[I][0];

  FileSystemObj.WriteFile(loader.data,abspath); 

  NextDownload();

  }

 function openHandler(event) {

  trace("openHandler: " + event);

  }

 function progressHandler(event) {

  var loader = URLLoader(event.target);

  trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);

  }

 function securityErrorHandler(event) {

  trace("securityErrorHandler: " + event);

  }

 function httpStatusHandler(event) {

  trace("httpStatusHandler: " + event);

  }

 function ioErrorHandler(event) {

  trace("ioErrorHandler: " + event);

  }

  function NextDownload(){

  I++;

  if(I<DownloadList.length){

  GetRemoteFile();

  }else{

  this.dispatchEvent(new Event("END_DOWNLOAD"));

  }

  }

 }

  }

Pour la lecture et le l’écriture des fichiers j’ai enfin créé une classe dans as3/fsystem/ qui s’appelle « AIRFsystem » dans le fichier AIRFsystem.as.

/as3/fsystem/AIRFsystem.as :

package fsystem
{

   ///AIR Class
   	import flash.net.*;
	import flash.filesystem.*;
	import flash.events.*;

    public class AIRFsystem
    {

     	public var DefaultFilesDir:String;//directory de destination 

		public function AIRFsystem():void{

				// DEFAULT  DIR
				var UserDescktopDir=File.desktopDirectory.resolvePath("MY_FILES");
				DefaultFilesDir=UserDescktopDir.nativePath;

		}

		 public function WriteFile(bytes,abspath:String){
			 	 var MyFile=new File(abspath);
				 var MyFileStream = new FileStream();
					 MyFileStream.open(MyFile, FileMode.WRITE);
					 MyFileStream.writeBytes(bytes, 0, bytes.length);
					 MyFileStream.close();
		 }

	}
}

La dernière étape avant la publication du fichier AIR a été la construction de la classe Main qui appelle les autres objets.
Voici la classe Main.as (elle doive être dans la racine du projet).

package
{
	import flash.display.*;
	import flash.events.*;
	import flash.system.*;

	import com.*;
	import fsystem.*;
	import layout.*;

   public class Main extends MovieClip
   {

	 private var XMLFilesListObj:XMLFilesList;
	 private var FileListPanelObj:FileListPanel;
	 private var DownloaderObj:Downloader;// ecriture des fichiers (settings et mp3)
	 private var AIRFsystemObj:AIRFsystem;

	 	public function Main() {
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.showDefaultContextMenu = false;
			XMLFilesListObj=new XMLFilesList();
			XMLFilesListObj.addEventListener("FILESLIST_ENDJOB",XML_EndJob);

       }

	    private  function XML_EndJob(event:Event){
		  	trace("XML end Job");
			FileListPanelObj=new FileListPanel(XMLFilesListObj.FilesListing);
			addChild(FileListPanelObj);
		    FileListPanelObj.addEventListener("START_DOWNLOAD",Start_Download);
	   }

	   private function Start_Download(event:Event){
	  		trace("start download");
			AIRFsystemObj=new AIRFsystem();
			DownloaderObj=new Downloader(FileListPanelObj.DownloadQueue,AIRFsystemObj);
			DownloaderObj.addEventListener("END_DOWNLOAD",End_Download);
	   }

	   private function End_Download(event:Event){
		   	trace("Done!");
	   }

   }//end class
}//end

Voici les codes source de ce petit download manager:
downloadmanager_demo.zip

Leave a Comment

Création d’une mapplet et d’un layer Google Earth

J’ai travaillé dernièrement sur la création d’une couche Google Earth que j’ai du ensuite convertir en Mapplet.
Voici en quelques lignes la solution technique que j’ai adopté.
Commençons par la création d’un fichier KML (Google Earth)

Création du KML:
Google propose pour la création du fichier KML d’utiliser un fichier Excel disponible ici :http://earth.google.com/outreach/tutorial_spreadsheet.html et accèsible depuis vos documents google. Rien de plus simple !
Je ne vais pas à rentrer dans les détails du  fonctionnement du  fichier Excel car cela  est très bien expliqué sur la doc de Google.
Pour la faire brève, dans ce fichier il y a plusieurs onglets mais vous en utiliserez que  2 ou 3.
Pour commencer, vous devriez compléter  le première onglet « start here ». C’est ici que vous rentrez le nom de votre KML, une petite  description, et les coordonnés d’ouverture de votre KML (latitude, longitude etc…).
Dans l’onglet « start here » vous avez 2 zones pour tester votre KML  à la fois sur Google Earth et à la fois sur google Maps (si votre Kml est compatible avec Google Maps).
Pour tester sur Google Earth il suffit de copier le code XML dans « View Placemarks in Google Earth » et de le coller dans « mes lieux préférées » dans Google Earth (dans la barre de gauche):
googlekml

Avant de tester votre KML, il vous faut d’abord rentrer les coordonnées et les données des points que vous désirez afficher sur Google Earth.
Pour cela allez dans l’onglet « PlacemarkData ».

Dans « placemarkData » vous avez plusieurs colonnes dont je vais en citer quelques une :

- Folder : ici vous pouvez rentrer le nom du dossier que vous voulez afficher sur la barre de gauche
- Placemark Name: le nom de votre « point » qui sera affiché  sur la barre de gauche
- Latitude du point
- Longitude du point
- Template : le numéro du template que vous avez choisi pour afficher les information une fois qu’on a cliqué sur le point.

Dans  le fichier Excel que vous avez récupéré sur le site de Google vous trouverez déjà quelques exemples dans la parties « PlacemarkData », vous pouvez modifier la liste des « markers » qui ont été mis comme exemple pour comprendre mieux le fonctionnement de chaque colonne.

Une fois que votre fichier Excel est complet vous pouvez créer le fichier KML que vous pourriez ensuite mettre à disposition en téléchargement sur votre site ou bien vous pouvez aussi le publier chez google ici: http://earth.google.com/intl/fr/submit.html

Pour créer le fichier KML, c’est très simple. Copiez et collez les code XML dans « mes lieux préférées » et ensuite faitez un click droite sur le nom de votre KML dans la barre de gauche de Google Earth est choisissez « enregistrer le Lieu sous… ». Donnez un nom à votre fichier et préférez l’extension  KMZ  car c’est une version comprimé du fichier KML, plus légère et pratique si vous pensez l’envoyer pour exemple par mail.

Création du Mapplet:
Pour la création du mapplet vous pouvez réutiliser le fichier KML pour l’intégrer directement sur GoogleMaps.

Voici d’abord la structure de base du fichier XML pour le Mapplet avec le KML:

<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Hello World"
             description="Displays a Hello World message in the left panel"
             author="Your name"
             author_email="your-email@gmail.com"
             height="150">
<Require feature="sharedmap"/>
</ModulePrefs>
<Content type="html"><![CDATA[
<script>

 var map;
 var geoXml;
 var toggleState = 1;

 if (GBrowserIsCompatible()) {
 geoXml = new GGeoXml("http://MONDOMAINE.com/MON_KML.kml");
 map = new GMap2(document.getElementById("map_canvas"));
 map.setCenter(new GLatLng(41.875696,-87.624207), 11);
 map.setUIToDefault();
 map.addOverlay(geoXml);
 }

 function toggleMyKml() {
 if (toggleState == 1) {
 map.removeOverlay(geoXml);
 toggleState = 0;
 } else {
 map.addOverlay(geoXml);
 toggleState = 1;
 }
 }

</script>

]]></Content>
</Module>

Avec cet méthode,j’ai eu quelques difficultés car je n’arrivais pas à interagir avec les points sur la carte en cliquant sur des liens présentes sur le sidebar de gauche.
J’ai donc choisi de reconstruire tout mon kml en javascript pour mapplet. IL ya surement des solutions pour arriver au même résultats tout en conservant le fichier kml mais mes recherches ont pris trop de temps et j’ai donc tranché.
Voici en quelque ligne javascript  la méthode que j’ai utilisé:
J’ai defini d’abord un array pour stocker tous les informations des mes points (coordonnées, nom et contenu)

var MapsContentArr=new Array();
MapsContentArr[0]=new Array();
	MapsContentArr[0]["name"]="marker 1";
	MapsContentArr[0]["lat"]=-33.933;
	MapsContentArr[0]["long"]=18.467;
	MapsContentArr[0]["content"]="Hello from marker 1!";

MapsContentArr[1]=new Array();
	MapsContentArr[1]["name"]="marker 2";
	MapsContentArr[1]["lat"]=-26.167;
	MapsContentArr[1]["long"]=28.033;
	MapsContentArr[1]["content"]="Hello from marker 2!";

J’ai ensuite utilisé mon array pour afficher les points sur la carte:

Tout d’abord j’ai creé un objet Gmap2:

var map = new GMap2();
map.setMapType(G_SATELLITE_MAP);

// Create our "tiny" marker icon
var baseIcon = new GIcon(G_DEFAULT_ICON);
baseIcon.image = "http://www.MONDOMAINE.com/MONICONE.png";
baseIcon.iconSize = new GSize(32, 32);

// Set up our GMarkerOptions object
markerOptions = { icon:baseIcon };

J’ai ensuite créé la fonction javascript qui sera appelé par mes liens sur le sidebar de gauche:

marker=new Array();
function open_Marker(nbmarker){
  if(nbmarker>-1){							

	 point = new GLatLng(MapsContentArr[nbmarker]["lat"],MapsContentArr[nbmarker]["long"]);
	 marker[nbmarker]= new GMarker(point,markerOptions);
	 map.addOverlay(marker[nbmarker]);

	 marker[nbmarker].openInfoWindowHtml(MapsContentArr[nbmarker]["content"]);

		GEvent.addListener( marker[nbmarker], "click", function() {
		 marker[nbmarker].openInfoWindowHtml(MapsContentArr[nbmarker]["content"]);
		});

  }

}

Voici maintenant mes 2 liens sur le sidebar:

<a href="#" onclick="open_Marker(0);return false;" >Open Marker 1</a>
<a href="#" onclick="open_Marker(1);return false;" >Open Marker 2</a>

Vous pouvez voir mon Mapplet et mon KML ici:
Le Mapplet
Le KML

Leave a Comment