Skip navigation.

digital-nation

Blog-note d'un informaticien procrastinate...

Posts tagged with "plugin"

Widgetize! Personnalisation d'une automatisation

, , , ...

Me revoici dans l'idée de faire un fil de l'information avec le journal Le Soir.
Après les récents articles sur l'automatisation d'un widget et plus particulièrement sur la manière de l'extérioriser, je me suis dit qu'il était temps de passer à la pratique.

Je vous avais récement montré en plus comment faire un widget, donc nous pouvons ici combiner les deux.
Alors en premier temps il nous faut récupérer le widget que nous avons créé pour notre blog, et qui est dans le répertoir Widget de Opera dans vos paramètres locaux (comme dit précédement il s'agit d'une simple archive à décompresser).

Une foix que cela est fait, nous obtenons la structure suivante :

  1. dossier JS
  2. dossier SKIN
  3. fichier CONFIG.XML
  4. fichier INDEX.HTML
  5. fichier CONFIG.JS


Récupérons maintenant le fil de l'information du journal Le Soir ( http://www.lesoir.be/services/rss/le_fil_Info/index.xml ). Pour ce faire, il suffit d'éditer la source du site et de récupérer la ligne qui vous intéresse dans les RSS... Cela s'identifie par un simple lien (balise HTML LINK) avec le type

RSS+XML (attribut de la balise LINK sur TYPE="APPLICATION/RSS+XML").

Maintenant il nous faut configurer le widget. Comme vous vous en douter, le fichier CONFIG.JS est là pour cela !
Donc éditons le dans le bloc-note et remplacons les données comme suit :

var skeletonConfig = {
feedURL : "http://www.lesoir.be/services/rss/le_fil_Info/index.xml",
feedTitle : "Journal Le Soir : le fil de l'info",
feedVersion : "generic",
maxItems : 10
};


Théoriquement votre widget est pret à l'emploi ! Vous enregistrer le tout, vous remettez au format archive et vous faite une lecture du fichier config.xml par Opera et le widget est lisible.

Mais comme vous vous en douter, il n'est pas parfais ! De nombreux anglicisme sont encore présent dans le widget. Normal me direz-vous car Opera Software,

l'éditeur maitre du widget que nous modifions, n'est pas du tout orienté vers le français !
Alors continuons à personnaliser le widget :

Ouvrons le fichier CONFIG.XML :

Et comme vous le voyez, nous pouvons donc le personnaliser :
  • La balise <widgetname> représente le nom du widget, changeons le par Le Soir,
  • La balise <description> elle représente la description du widget, placer y ce que vous y désirez comme description sans faire dans la longueur,
  • Par la suite, ce qui est entre les balise d'identification (<id>), représente l'identification du widget, le HOST représente l'hôte d'hébergement du widget,


Le NAME est le nom et REVISED est la dernière revision du widget... Jusque là que du connus que nous avons déjà passé en revue lors de la création du premier Widget.
Vous pouvez maintenant déterminer la hauteur et la largeur (balise WIDTH et HEIGHT) en pixel.
La suite reste tout aussi connue par les auteurs (nom, liens, organisation...) !

Ceci devrait donner cela :

<?xml version="1.0"?>
<widget>
  <widgetname>Le Soir.be</widgetname>
  <description>Le fil de l'information</description>
  <id>
     <host>localhost</host>
     <name>Lecteur RSS</name>
     <revised>2006-08-12</revised>
  </id>
  <width>400</width>
  <height>250</height>
  <author>
    <name>Opera widgets</name>
    <link>http://widgets.opera.com/</link>
    <organization>Opera Software ASA</organization>
  </author>
</widget>


Passons maintenant à la suite, le plus amusant, franciser l'interface...
Pour ce faire, très simplement éditons le fichier INDEX.HTML comme il se doit :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!--
/**
 * Copyright (c) 2006, Opera Software ASA
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Opera Software ASA nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY OPERA SOFTWARE ASA AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL OPERA SOFTWARE ASA AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
-->
<!-- 
Auteur : Opera Software ASA - version d'origine
Groumphy (http://users.skynet.be/digital-nation/blog/) - modification 
Licence : (c) Opera Software ASA 2006 All rights reserved
Changelog : francisation
personnalisation du widget
Version : 1.0.0- version d'origine
1.0.1- version modifiée par Groumphy
-->
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Lecteur RSS</title>
<link rel="stylesheet" type="text/css" href="skin/base.css">
<link rel="stylesheet" type="text/css" href="skin/skin-specific.css">
<script type="text/javascript" src="config.js"></script>
<script type="text/javascript" src="js/date.js"></script>
<script type="text/javascript" src="js/general.js"></script>
<script type="text/javascript" src="js/animation.js"></script>
<script type="text/javascript" src="js/Feed.js"></script>
<script type="text/javascript" src="js/Tooltip.js"></script>
<script type="text/javascript" src="js/parsers.js"></script>
<script type="text/javascript" src="js/script.js"></script>
</head>
<body>
<div id="wrapper">
<div id="header">
<div id="logo"></div>
<h1 id="widgetTitle">&nbsp;</h1>
<span id="unread" title="Unread items">0</span>
<button id="flip">Basculer</button>
<button id="close" onclick="window.close()">Fermer</button>
</div>
<div id="cbody">
<div id="content">
<ul id="itemList"></ul>
<div id="back">
<h2>Widgetize!</h2>
<p><a href="http://widgets.opera.com/widgetize/">Widgetize!</a> est un produit de Opera Software sur lequel vous 

pouvez créer vos propres 
                widget. (version modifiée par <a href="http://users.skynet.be/digital-nation/blog/">Groumphy</a>)</p>
<p class="downcenter"><input type="checkbox" id="disanim">Désactiver animations</p>
</div>
</div>
</div>
<div id="footer">
<button id="reload">Recharger</button>
<span id="lastUpdate">&nbsp;</span>
<button id="expandMinimize" class="minimize"></button>
</div>
</div>
</body>
</html>

Parfais... Maintenant il nous faut voir du coté Javascript. Cela fait un petit plus non négligeable d'avoir des dates à l'européenne et surtout que ce soit inscrit en français.
Alors éditons le fichier Date.js se trouvant dans le dossier JS et changer les deux premières variables par des contenus francisé :
var months = [
'Janvier',
'Fevrier',
'Mars',
'Avril',
'Mai',
'Juin',
'Juillet',
'Aout',
'Septembre',
'Octobre',
'Novembre',
'Decembre'
];
var tw = {
second : 'seconde',
seconds : 'secondes',
minute : 'minute',
minutes : 'minutes',
hour : 'heure',
hours : 'heures',
yesterday : 'Hier',
and : 'et',
ago : 'depuis',
today : 'Ce jour',
at : ', ',
future : 'dans le futur',
date : '%DATE% %MONTH%',
longdate : '%DATE% %MONTH%, %YEAR%'
}

Comme vous avez pu le remarquer, j'ai aussi adapté la date dans un ordre européen (voir variable date et longdate dans la zone mémoire tw)...

Vous avez aussi la possiblité de modifier la fonction de calcul de l'heure. En effet, la variable ago de la zone de mémoire tw se situe à la fin (dans la version anglaise), hors en français elle devrait se placer à l'avant...

Modifion alors l'appel de la fonction dans une variable de la manière suivante :
Date.prototype.toAge = function() {

var now = new Date();
var yesterday = new Date( now.getFullYear(), now.getMonth(), now.getDate() );

var delta = yesterday.getTime() - this.getTime();
var ticks = now.getTime() - this.getTime();

if ( delta > 0 || ticks < 0 ) {
// Yesterday or before
if ( delta < 1000 * 60 * 60 * 24 && ticks > 0 ) {
// Yesterday
return tw.yesterday;
} else {
// Long ago
var d = (now.getFullYear() != this.getFullYear()) ? tw.longdate.replace( '%YEAR%', this.getFullYear() ) : tw.date;
d = d.replace( '%MONTH%', months[this.getMonth()] ).replace( '%DATE%', this.getDate() );
if (ticks < 0) d += ' (' + tw.future + ')';
return d;
}
} else {
// Today

if (ticks < 0) {
return tw.future;
}
// Seconds
ticks = Math.floor( ticks / 1000 );
if (ticks < 60) {
//return ticks + ' ' + (ticks == 1 ? tw.second : tw.seconds) + ' ' + tw.ago;
return tw.ago + ' ' + ticks + ' ' + (ticks == 1 ? tw.second : tw.seconds);
}
// Less than, or an hour ago
ticks = Math.floor( ticks / 60 );
if (ticks <= 60) {
if (ticks < 60) {
//return ticks % 60 + ' ' + (ticks == 1 ? tw.minute : tw.minutes) + ' ' + tw.ago;
return tw.ago + ' ' + ticks % 60 + ' ' + (ticks == 1 ? tw.minute : tw.minutes);
} else {
return tw.ago + ' ' + '1 ' + tw.hour;
}
}
// Less than, or two hours ago
if (ticks <= 120) {
if (ticks < 120) {
return tw.ago + ' ' + '1 ' + tw.hours + ' ' + tw.and + ' ' + ticks % 60 + ' ' +
(ticks == 1 ? tw.minute : tw.minutes);
} else {
return tw.ago + ' ' + '2 ' + tw.hours;
}
}
// Otherwise, write out the time
else {
return tw.today + tw.at + ' ' + padZero(this.getHours()) + ':' + padZero(this.getMinutes());
}
}
};


Hum, voila qui est fait pour une grande partie et c'est bientôt terminé. Il ne nous reste plus que quelques petites modifications et le tour est joué !
Ouvrons maintenant SCRIPTS.JS et dans la changeons la fonction oneNewItemHandler comme ceci :
function onNewItemsHandler(noChange, err) {
/* Advanced - lastupdate */
    updateStatus(err);
    /* End advanced */

var container = document.getElementById('itemList');
var list = feed.getItemList();

   /* Advanced - modified for lastupdate */
if (err) {
        if (container.firstChild) {
    return;
    }

var li = document.createElement('li');
li.appendChild( document.createTextNode( '(Affichage RSS non possible)' ) );
container.insertBefore( li, container.firstChild );
li.id = 'noContent';
return;
}
   /* End advanced */

if (list.length == 0) {
container.innerHTML = '';
var li = document.createElement('li');
li.appendChild( document.createTextNode( '(Pas de News)' ) );
container.appendChild(li);
li.id = 'noContent';
return;
}

// Unchanged feed, leave it alone
    if (noChange) return;

// Display feed items
container.innerHTML = '';
var pointer = null, li = null, content = null;

for (var i = 0; pointer = list[i]; i++) {
li = document.createElement('li');
li.className = pointer.read ? 'read' : '';
li.guid = pointer.getGUID();
container.appendChild( li );

var tit = pointer.getTitle() || '(Pas de titre)';
if ( typeof tit == 'string' ) tit = document.createTextNode( tit );
var h2 = document.createElement('h2');
h2.className = 'postTitle';
h2.appendChild( tit );
li.appendChild( h2 );

var content = document.createElement('div');
var h3 = document.createElement('h3');
h3.className = 'dateTime';
/* Advanced - lastupdate */
var pub = pointer.getDate();
h3.appendChild( document.createTextNode( pub ? pub.toAge() : '(Pas de date)' ) );
h3.timestamp = pub ? pub.getTime() : 0;
/* End advanced */
        content.appendChild( h3 );
li.appendChild( content );
li.expander = content;

var desc = pointer.getDesc() || document.createTextNode( '(No text)' );
if ( typeof desc == 'string' ) desc = document.createTextNode( desc );
content.appendChild( desc );

var link, href = pointer.getLink();
if ( href ) {
link = document.createElement('a');
link.href = href;
link.appendChild( document.createTextNode( ' Voir ' ) );
} else {
link = document.createTextNode( '(Pas de lien)' );
}
link.className = 'morelink';
content.appendChild(link);

}

    updateUnread();

/* Advanced - fancy unread */
if (feed.getUnreadCount() > 0) {
document.getElementById('unread').style.visibility = 'visible';
var animation = document.getElementById('unread').createAnimation();
animation.style.opacity = 0;
animation.speed = 5;
animation.accelerationProfile = animation.constant;
animation.addAnimation('opacity', animation.style.opacity, '1').run();
}
/* End advanced */
}

En bref nous avons simplement traduit les commentaires données dans les structures conditionnelles.

Après ces quelques manipulations, il n'y a rien d'autres à faire.
Si vous recompiler le tout, et que vous proposer cela en téléchargement, il n'y a aucun soucis pour l'exécution du widget.

Ce dernier article devrait pouvoir vous aider sur pas mal de problème de lecteur RSS, en essayant que ce soit le cas.

filinfoLeSoir.zip

Insertion d'élément Flash dans une page (x)HTML

, , , ...

L'inclusion d'un élément nécessitant le plugin Adobe (ex Macromédia) Flash n'est pas une mince affaire.

Dans le meilleur des cas, vous aurez peut-être l'occasion de voir votre plugin s'afficher sous un navigateur, parfois sous deux... Dans le pire, vous ne verrez rien !

Bien entendu, beaucoup se sont penché sur la question et de nombreuses solution sont parues. Certaines plus faciles que d'autres.

Passons en revues quelques-unes de ces solutions.

La solution "écrire en dur"

Ici point de petite astuce, point de renvois au site de téléchargement ou autre... Ce qui se passe, nous écrivons en "dur" (insertion directe du code) dans la page.
Pour ce faire, nous travaillons par la balise OBJECT. Celle-ci est gerée via une autre balise PARAM... Qui comporte donc la paramétrisation de la première.

Lorsque nous utilisons un éditeur de page en WYSIWYG, nous avons bien souvent un code de ce style :
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="200" 
height="20" title="play it !" bgcolor="#999999">
  <param name="movie" value="monflash.swf">
  <param name="quality" value="high">
<param name="bgcolor" value="#999999">
  <embed src="monflash.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" 
type="application/x-shockwave-flash" width="200" height="20"></embed>
</object>


Hors lorsque nous validons notre page HTML par le W3C, nous obtenons une dizaine d'erreur facilement. Mais alors comment faire.

Lorsque nous consultons différents sites (qui nous renseigne sur une méthode plus "valide"), nous obtenons le code suivant :
<object type="application/x-shockwave-flash" data="fichierflash.swf" width="600" height="20">
<param name="movie" value="fichierflash.swf" />
<param name="wmode" value="transparent" />
<p>Image ou texte alternatif</p>
</object>

Cf. Css.AlsaCreations.com
Cette dernière méthode est compatible par tous les navigateurs. Parfais me direz-vous, nous gérons tout aussi le contenu réel (le Flash) que le contenu alternatif (via un texte ou une image).

Mais cela serait beaucoup trop simple si... Il n'y avait pas incompatibilité de version de Flash (sur les éléments avancés).
De fait, d'autres personnes se sont à nouveau penchées sur le problème et ont sortis quelques JavaScript des plus sympathiques.
Je citerais donc deux méthodes qui m'ont particulièrement séduites : la méthode Satay, la méthode du FlashObject...
Toutes deux inclues un système de détection, de redirection etc. permettant d'avoir la version souhaitée ainsi que la visualisation correcte.

De véritable petites merveilles... Mais un peu (voir beaucoup) trop complèxe pour moi.

Alors je me suis "amusé" à pouvoir combiner les deux... Mais sans aucuns systèmes de redirection ou téléchargement. J'utilise très simplement du Javascript pour écrire l'OBJECT Flash et s'il n'est pas affiché, je puis donc utiliser le dernier paramètre pour un contenu alternatif.
Les méthodes Satay et FlashObject intègrent bien entendu cela.

Cependant, j'ai décidé de continuer l'originalité par l'utilisation de la balise NoScript définie identiquement à la manière du contenu alternatif de la balise OBJECT.
De fait, peut importe que le navigateur gère Flash ou non, Javascript ou non, il y aura l'affichage du contenu alternatif.

Nous pourrions aussi afficher dans la balise NoScript le Flash en soi... Une idée comme une autre.
Passons en revue maintenant le code :
En javascript
// Auteur : Groumphy
// Version : v1.0.1
// Licence : CreativeCommons Partage à l'identique BE
// SWF = le fichier Flash
// S_SWF = largeur du Flash
// H_SWF = hauteur du Flash
// ALT_IMG = image alternative
// ALT_TXT = texte alternatif 
function _gFlash(swf, w_swf, h_swf, alt_img, alt_txt) {
document.write('<object type="application/x-shockwave-flash" data="' +
 swf + '" width="' + w_swf + '" height="' + h_swf + '">');
    document.write('<param name="movie" value="' + swf + '">');
document.write('<param name="wmode" value="transparent">');
if ((alt_img != '') || (alt_img != ' ')) { 
document.write('<img src="' + alt_img + '" width="' + w_swf + '" height="' 
+ h_swf + '" alt="">'); }
if ((alt_txt != '') || (alt_txt != ' ')) { 
document.write('<p>' + alt_txt + '</p>'); }
document.write('</object>'); }


En HTML :
<script language="javascript1.1" type="text/javascript">
_gFlashHtml('monflash.swf', '400', '300', '', '');
</script>
<noscript>
<object type="application/x-shockwave-flash" data="monflash.swf" width="600" height="20">
<param name="movie" value="fichierflash.swf" />
<param name="wmode" value="transparent" />
<p>Image ou texte alternatif</p>
</object>
</noscript>


J'ai effectué les tests sous différents navigateurs et systèmes d'exploitation, mais je n'ai pas constaté de problèmes majeurs (excepté ceux que je cite si souvent relatif à l'utilisation du Javascript et des plugins... En rapport aux utilisateurs [visiteur] les plus pointus au niveau des langages clients etc.).

Que pensez-vous d'une méthode pareille ?
Quels serait les avantages ou inconvéniants...
December 2009
M T W T F S S
November 2009January 2010
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31