Web development
Suivre le flux RSS des articles de cette rubrique
Suivre le flux RSS des commentaires de cette rubrique
[1] 2 3 4

Détecter les sites que vos visiteurs utilisent
par Skreo, le 1 Août 2008 à 02:34Je me suis souvenu d'un article très intéressant sur lequel j'étais tombé il y a un ou deux mois, présentant une classe javascript permettant de détecter quels réseaux sociaux utilisent les visiteurs. En regardant le code de plus prêt, je l'ai trouvé compliqué pour pas grand chose, avec l'utilisation d'une iframe et un code pas très optimisé.
Voici donc un code que je viens de pondre, parce que je pense qu'il pourra être utile, aussi bien pour vous que pour moi
J'utilise ici le framework Mootools 1.2 , mais je pense que c'est facilement adaptable à d'autres. Le principe est simple, on utilise une "faille" du CSS qui consiste à récupérer le style de liens après avoir appliqué un style particulier aux liens visités ("a:visited").Une petite démo pour commencer : checkvisited.html
On va donc commencer par faire un peu de CSS :
a.test_visited { display: block; }
a.test_visited:visited { display: none; }C'est tout pour le CSS !
Maintenant, le Javascript :// Implémentation de la fonction checkVisited
// pour les chaînes de caractères (String)
String.implement({
checkVisited : function(){
var e = (new Element("a", {
href: this,
"class" : "test_visited"
}))
.inject(document.body),
b = e.getStyle("display")=="none";
e.destroy();
return b;
}
});
// Implémentation de la fonction checkVisited pour
// les tableaux (Array) : tester une liste d'urls
Array.implement({
checkVisited : function(){
var b = false;
this.each(function(s){
if(s.checkVisited())
b = true;
})
return b;
}
});Ces deux implémentations permettent de vérifier une URL ou une liste d'URLs.
On va reprendre l'exemple des réseaux sociaux que traite Aza Raskin dans son article. D'abord, on crée un conteneur pour l'affichage du résultat :
Ensuite, on crée la liste et on la traite :
// Liste de réseaux sociaux
var sites = {
"Digg": ["http://digg.com", "http://digg.com/login"],
"Reddit": ["http://reddit.com", "http://reddit.com/new/", "http://reddit.com/controversial/", "http://reddit.com/top/", "http://reddit.com/r/reddit.com/", "http://reddit.com/r/programming/"],
"StumbleUpon": ["http://stumbleupon.com"],
"Yahoo Buzz": ["http://buzz.yahoo.com"],
"Facebook": ["http://facebook.com/home.php", "http://facebook.com", "https://login.facebook.com/login.php"],
"Del.icio.us": ["https://secure.del.icio.us/login", "http://del.icio.us/", "http://delicious.com"],
"MySpace": ["http://www.myspace.com/"],
"Technorati": ["http://www.technorati.com"],
"Newsvine": ["https://www.newsvine.com", "https://www.newsvine.com/_tools/user/login"],
"Songza": ["http://songza.com"],
"Slashdot": ["http://slashdot.org/"],
"Ma.gnolia": ["http://ma.gnolia.com/"],
"Blinklist": ["http://www.blinklist.com"],
"Furl": ["http://furl.net", "http://furl.net/members/login"],
"Mister Wong": ["http://www.mister-wong.com"],
"Current": ["http://current.com", "http://current.com/login.html"],
"Menaeme": ["http://meneame.net", "http://meneame.net/login.php"],
"Oknotizie": ["http://oknotizie.alice.it", "http://oknotizie.alice.it/login.html.php"],
"Diigo": ["http://www.diigo.com/", "https://secure.diigo.com/sign-in"],
"Funp": ["http://funp.com", "http://funp.com/account/loginpage.php"],
"Blogmarks": ["http://blogmarks.net"],
"Yahoo Bookmarks": ["http://bookmarks.yahoo.com"],
"Xanga": ["http://xanga.com"],
"Blogger": ["http://blogger.com"],
"Last.fm": ["http://www.last.fm/", "https://www.last.fm/login/"],
"N4G": ["http://www.n4g.com"],
"Faves": ["http://faves.com", "http://faves.com/home", "https://secure.faves.com/signIn"],
"Simpy": ["http://www.simpy.com", "http://www.simpy.com/login"],
"Yigg": ["http://www.yigg.de"],
"Kirtsy": ["http://www.kirtsy.com", "http://www.kirtsy.com/login.php"],
"Fark": ["http://www.fark.com", "http://cgi.fark.com/cgi/fark/users.pl?self=1"],
"Mixx": ["https://www.mixx.com/login/dual", "http://www.mixx.com"],
"Google Bookmarks": ["http://www.google.com/bookmarks", "http://www.google.com/ig/add?moduleurl=bookmarks.xml&hl=en"],
"Subbmitt": ["http://subbmitt.com/"]
},
t = []; // Variable dans laquelle on va stocker la liste de sites visités par l'utilisateur
// On vérifie pour chaque site de la liste
for(var i in sites){
if(sites[i].checkVisited())
t.push(i);
}
// On affiche le résultat
$("visited_sites").set("html", "<strong>Sites visités : </strong>" + t.join(", "));C'est fini !
Chez moi, ça fonctionne impeccablement avec Firefox 3, Opéra 9.5, IE 6, et IE 7.
Si vous avez un problème d'incompatibilité ou une suggestion, n'hésitez pas ! Par exemple, on pourrait, comme Aza, traiter pour une URL quelconque l'URL avec et sans les "www".Merci de me faire un petit lien de retour si vous utilisez ce script quelque part

4 commentaires[PHP] Enlever tous les accents d'une chaîne
par Skreo, le 25 Juillet 2008 à 20:46Voici ma fonction pour enlever tous les accents d'une chaîne de caractères tout en respectant l'encodage (cette fonction traite très bien les textes UTF-8 par exemple) :
function removeAccents($txt){
$txt = str_replace('œ', 'oe', $txt);
$txt = str_replace('Œ', 'Oe', $txt);
$txt = str_replace('æ', 'ae', $txt);
$txt = str_replace('Æ', 'Ae', $txt);
mb_regex_encoding('UTF-8');
$txt = mb_ereg_replace('[ÀÁÂÃÄÅĀĂǍẠẢẤẦẨẪẬẮẰẲẴẶǺĄ]', 'A', $txt);
$txt = mb_ereg_replace('[àáâãäåāăǎạảấầẩẫậắằẳẵặǻą]', 'a', $txt);
$txt = mb_ereg_replace('[ÇĆĈĊČ]', 'C', $txt);
$txt = mb_ereg_replace('[çćĉċč]', 'c', $txt);
$txt = mb_ereg_replace('[ÐĎĐ]', 'D', $txt);
$txt = mb_ereg_replace('[ďđ]', 'd', $txt);
$txt = mb_ereg_replace('[ÈÉÊËĒĔĖĘĚẸẺẼẾỀỂỄỆ]', 'E', $txt);
$txt = mb_ereg_replace('[èéêëēĕėęěẹẻẽếềểễệ]', 'e', $txt);
$txt = mb_ereg_replace('[ĜĞĠĢ]', 'G', $txt);
$txt = mb_ereg_replace('[ĝğġģ]', 'g', $txt);
$txt = mb_ereg_replace('[ĤĦ]', 'H', $txt);
$txt = mb_ereg_replace('[ĥħ]', 'h', $txt);
$txt = mb_ereg_replace('[ÌÍÎÏĨĪĬĮİǏỈỊ]', 'I', $txt);
$txt = mb_ereg_replace('[ìíîïĩīĭįıǐỉị]', 'i', $txt);
$txt = str_replace('Ĵ', 'J', $txt);
$txt = str_replace('ĵ', 'j', $txt);
$txt = str_replace('Ķ', 'K', $txt);
$txt = str_replace('ķ', 'k', $txt);
$txt = mb_ereg_replace('[ĹĻĽĿŁ]', 'L', $txt);
$txt = mb_ereg_replace('[ĺļľŀł]', 'l', $txt);
$txt = mb_ereg_replace('[ÑŃŅŇ]', 'N', $txt);
$txt = mb_ereg_replace('[ñńņňʼn]', 'n', $txt);
$txt = mb_ereg_replace('[ÒÓÔÕÖØŌŎŐƠǑǾỌỎỐỒỔỖỘỚỜỞỠỢ]', 'O', $txt);
$txt = mb_ereg_replace('[òóôõöøōŏőơǒǿọỏốồổỗộớờởỡợð]', 'o', $txt);
$txt = mb_ereg_replace('[ŔŖŘ]', 'R', $txt);
$txt = mb_ereg_replace('[ŕŗř]', 'r', $txt);
$txt = mb_ereg_replace('[ŚŜŞŠ]', 'S', $txt);
$txt = mb_ereg_replace('[śŝşš]', 's', $txt);
$txt = mb_ereg_replace('[ŢŤŦ]', 'T', $txt);
$txt = mb_ereg_replace('[ţťŧ]', 't', $txt);
$txt = mb_ereg_replace('[ÙÚÛÜŨŪŬŮŰŲƯǓǕǗǙǛỤỦỨỪỬỮỰ]', 'U', $txt);
$txt = mb_ereg_replace('[ùúûüũūŭůűųưǔǖǘǚǜụủứừửữự]', 'u', $txt);
$txt = mb_ereg_replace('[ŴẀẂẄ]', 'W', $txt);
$txt = mb_ereg_replace('[ŵẁẃẅ]', 'w', $txt);
$txt = mb_ereg_replace('[ÝŶŸỲỸỶỴ]', 'Y', $txt);
$txt = mb_ereg_replace('[ýÿŷỹỵỷỳ]', 'y', $txt);
$txt = mb_ereg_replace('[ŹŻŽ]', 'Z', $txt);
$txt = mb_ereg_replace('[źżž]', 'z', $txt);
return $txt;
}On peut faire plus simple, certes, mais contrairement à ce qu'on peut voir habituellement, cette fonction traite véritablement tous les accents existants, et fonctionne avec tous les encodages.
un commentaireMes conventions en programmation
par Skreo, le 11 Juillet 2008 à 19:40 (modifié le 11/07/2008 à 20:54)On a tous nos petites habitudes de programmation : quel type d'indentation, où placer les accolades, notation hongroise, espacements...etc.
Je vais vous présenter les miennes, non pas pour tenter de les imposer (d'ailleurs tout n'est pas forcément bien), mais pour échanger, savoir ce que vous en pensez, et savoir quelles sont les vôtres. Je ne parlerai ici que de l'aspect visuel de la programmation, pas de la structure des fichiers, des frameworks...Avant tout, un petit exemple en PHP pour illustrer mes conventions :
<?php
$monTableau = array('H', 'e', 'l', 'l', 'o');
$txt = '';
$n = 2;
for($i=0; $i<count($monTableau); $i++){
$txt .= $monTableau[$i];
$n = pow($n, 2);
}
if($n % (strlen($txt)+1)==0)
$txt .= ' World';
echo $txt;
?>Notation :
J'utilise la notation lowerCamelCase pour nommer mes variables, fonctions, classes, et méthodes.Indentation :
Tabulation de la largeur de 4 espace.
Je prends soin de bien indenter tout les blocs. Logique diront certains, mais ce n'est pas le cas partout...Accolades :
Accolade ouvrante à la fin de la ligne de définition de la boucle. Accolade fermante sur une nouvelle ligne, au même niveau que la définition de la boucle.
Pas d'accolades pour un bloc mono-ligne. (par exemple un if suivi d'une seule instruction).Espaces :
Pour les virgules et les point-virgules : pas d'espace avant, un espace après.
Pas d'espace entre les noms de fonction et la parenthèse ouvrante. Idem pour les boucles.
Pas d'espace entre la parenthèse fermante et l'accolade ouvrante dans les boucles.
Pas d'espace entre le else et le if dans les else if.
Un espace de part et d'autre des opérateurs de modification (=, +=, *=, ...).
Pas d'espace pour les opérateurs de comparaison (==, <=, >=) et pour les opérateurs de modification dans les boucles (for, while, if), sauf pour les longues expressions.Guillemets
En php, j'utilise uniquement les guillemets simples (apostrophe), sauf pour afficher des caractères spéciaux (\r, \n ...).
Dans les autres langages, des guillemets doubles.Commentaires
En moyenne un commentaire mono-ligne toutes les 10 lignes, avant un bloc, pour expliquer ce qu'on fait. Je pense qu'ils sont important pour la compréhension générale du code, mais qu'il ne faut pas en abuser.
Pas de bloc de 30 lignes au début des pages, au pire 2 ou 3 lignes.Allez j'ai envie de faire mon chieur, je crée une chaîne ! Je tague divarvel, Darklg, Babozor, et TomClarks qui seront obligés conviés à décrire à leur tour leurs conventions sur leur blog et faire suivre la chaîne

6 commentairesInternationalisation d'un site web
par Skreo, le 9 Juillet 2008 à 02:03 (modifié le 09/07/2008 à 03:27)Je me suis demandé il y a quelques temps quelle serait la meilleure solution pour traduire facilement un site web en plusieurs langues, tout en gardant une facilité de mise à jour, une accessibilité optimale, et des urls correctes pour le référencement. Le sujet a certes beaucoup été traité, mais j'ai trouvé très peu de solutions pratiques, jolies et performantes sur le web.
Certains webmasters recopient simplement l'intégralité de leur site dans un autre dossier ou sur un autre domaine, puis le traduisent. Oublions tout de suite cette solution... Il faut donc opter pour une solution dynamique, que je traiterai ici en php.
URL et détection de la langue
Avant de traduire le site, il faut être capable de détecter la langue du visiteur, de lui proposer de changer de langue, et de mémoriser son choix :
<?php
session_start(); // Démarrage de la session pour la sauvegarde du choix de la langue
$langs = array('en', 'fr', 'it'); // Liste des langues
// Si la langue a été changée par get ou cookie, on enregistre la modif
if(isset($_GET['lang']) && in_array($_GET['lang'], $langs) && (!isset($_SESSION['lang']) || $_SESSION['lang']!=$_GET['lang']))
$_SESSION['lang'] = $_GET['lang'];
else if(isset($_COOKIE['lang']) && in_array($_COOKIE['lang'], $langs) && (!isset($_SESSION['lang']) || $_SESSION['lang']!=$_COOKIE['lang']))
$_SESSION['lang'] = $_COOKIE['lang'];
// Si aucune langue n'est définie, on prend celle du navigateur du visiteur
if(!isset($_SESSION['lang'])){
$lang = strtolower(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2));
$_SESSION['lang'] = in_array($lang, $langs) ? $lang : $langs[0];
}
// Si le cookie de la langue n'est pas défini ou est différent de la var de session, on le définit
if(!isset($_COOKIE['lang']) || $_SESSION['lang']!=$_COOKIE['lang'])
setcookie('lang', $_SESSION['lang'], time()+60*24*3600, '/');
// Variable $lang locale que nous utiliserons plus loin
$lang = $_SESSION['lang'];
?>Ce code devra être appelé au tout début de chaque page du site. Nous avons maintenant notre moyen de détection et de mémorisation de la langue.
Ensuite, nous allons prendre l'exemple d'URLs du type http://www.monsite.com/lang/page.html, ce qui a l'avantage de bien référencer toutes les pages dans toutes les langues traduites. Mais nous pourrions tout aussi bien garder des URLs classiques dans le cas d'un service accessible uniquement aux utilisateurs connectés : par exemple Twitter. La langue serait alors enregistrée dans les paramètres de l'utilisateur.
Pour cela, mettons en place un .htaccess avec de l'URL Rewriting à la racine :
RewriteEngine On
RewriteRule ^(en|fr|it)/([^\?]+)?(\?(.*))?$ /$2?$4&lang=$1 [QSA,L]
Et voilà, désomais, un accès à la page http://www.monsite.com/fr/page.php appellera la page page.php à la racine du site en lui passant la variable GET lang=fr, ce qui aura pour effet avec le script précédent d'enregistrer "fr" comme langue dans le cookie et la variable de session du visiteur.Proposons maintenant au visiteur de choisir sa langue tout en restant sur la même page, au cas où elle aurait été mal détecté (navigateur en anglais pour un français par exemple) :
<?php
$URI = $_SERVER['REQUEST_URI'];
if($URI=='/') $URI = '/'.$lang.'/';
?>
<a href="<?php echo preg_replace('#^/[a-z]{2}#', '/en', $URI); ?>"><img src="/images/en.png" alt="English" /></a>
<a href="<?php echo preg_replace('#^/[a-z]{2}#', '/fr', $URI); ?>"><img src="/images/fr.png" alt="Français" /></a>
<a href="<?php echo preg_replace('#^/[a-z]{2}#', '/it', $URI); ?>"><img src="/images/it.png" alt="Italiano" /></a>
Vous trouverez plein de super icônes de drapeaux ici.Stockage des traductions
On peut imaginer deux solutions de stockage pour les textes traduits. J'ai retenu la deuxième :
1- Première solution : Une fonction getText choisissant entre plusieurs textes proposés. Par exemple
<?php
function getText($en, $fr){
global $lang;
if($lang=='fr') return $fr;
else return $en;
}
// Affichage d'un texte traduit :
echo getText('Text in english', 'Texte en français');
?>
Ce n'est pas très pratique, et pas très lisible dès que les textes deviennent un peu gros et le nombre de langues grand.2- Deuxième solution : Le stockage des textes dans divers fichiers : un fichier par langue. L'avantage ici est qu'on peut traduire (ou faire traduire) le site en ajoutant simplement un seul fichier. Nous stockerons les fichiers en.php, fr.php, et it.php dans un dossiers langs. Il suffira d'ajouter cette ligne après la détection de la langue :
require_once 'langs/'.$lang.'.php';Ensuite, nous avons encore le choix entre plusieurs méthodes de stockage. Les deux principalement utilisées consistent soit à créer une constante par texte, soit un grand tableau avec une entrée par texte. La méthode des constantes a l'avantage d'être performante mais n'est vraiment pas propre. Celle du tableau n'est pas non plus des plus performantes. Je parle bien sûr ici pour une grande échelle : prévoyons 15 000 entrées pour voir réellement les différences entre les méthodes.
Je vais vous proposer une autre méthode, une sorte de compromis, mais performante, pratique, et plus lisible. Elle consiste à utiliser une classe pour stocker les textes sous forme de constantes. Ces constantes restent dans la classe, c'est donc propre, l'accès y est très facile, et les performances sont très bonnes (j'avais fait un benchmark il y a quelques mois, mais je ne l'ai plus sous la main...). Nous allons donner un nom très court à cette classe, par exemple "_". Voici un exemple pour le fichier fr.php, il suffit ensuite de copier le fichier et de le traduire pour les autres langues :
<?php
// Classe de stockage :
final class _ {
const TEXT1 = 'Mon premier texte en français';
const EXEMPLE = 'Ceci est un exemple';
const NUM = 'un, deux, trois';
}
?>Puis pour afficher le texte :
<?php
// Affichage du texte :
echo _::TEXT1 . '<strong>'. _::EXEMPLE . '</strong><br />'. _::NUM;
?>Et voilà, j'espère que ce tuto pourra servir à quelqu'un. Qu'en pensez-vous ? Quelles solutions utilisez-vous ?
4 commentairesTest de TagMyPod à la GeekChic
par Skreo, le 4 Juin 2008 à 20:39
TagMyPod, qui réalise des gravures sur téléphones portables et lecteurs MP3 (25 € environ), était présent hier soir à la GeekChic et offrait à quiconque le voulait une gravure !
Et bien sûr j'en ai profité pour graver mon logo favori sur mon LG Viewty

aucun commentaire
[1] 2 3 4




Haut de page
