Skip navigation.

digital-nation

Blog-note d'un informaticien procrastinate...

Posts tagged with "widget"

Widget : la foulée productive

, , , ...

Dans la même foulée que j'ai donné le premier Widget pour le journal Le Soir en ligne, j'ai produit quelques autres... Le Standaard, la DH, La Gazet van Antwerp, Le Monde, AlsaCreations.com ...

Devrais-je les mettres en lignes ?
Ou à la demande ?

Un petit instant de réfléxion s'impose... Et vos avis aussi.

Widget en ligne

, , , ...

Il y a quelques jours je vous informais de la publication de mon premier Widget basé sur Widgetize! que j'avais aussi traduit, modifié etc...

Ce premier Widget reprenais le fil de l'information du journal Le Soir en ligne. Et bien il a été accepté de tout plein gré.

J'y explique aussi comment intégrer le widget si on a une archive.
Merci aux mainteneur de la communauté Opera pour leur confiance !

Premier widget envoyé !

, , , ...

Après avoir analysé, reporté et enfin écrit quelques articles sur les widgets, je me suis décidé à franchir le pas.

J'ai en effet soumis il y a quelques minutes à peine un widget basé sur le fil de nouvelle du journal LeSoir.
Ce widget comme beaucoup qui suivrons a mon avis sera basé simplement sur Widgetize!, le module automatisé de fabrication de widget.

Quelques idées me sont venue, l'une à la suite de l'autre...
Et dans la continuité, je joins à ce topics, un widget pour Alsacreations.com, une communauté Web destinée aux standards.
Bien évidement, le widget a aussi été soumis sur le forum.

J'en attend toujours les commentaires.

Widget Alsacreations
Widget LeSoir.be

Edit : légère mise à jour des widgets suite à une remarque du forum Alsacreations.com !

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

Créer son propre widget via l'automatisation

, , , ...

Comme vu dans le post précédent sur le générateur de widget, je me pose la question et la pose, pourquoi n'y a t'il pas directement moyen de télécharger ce widget ?

Actuellement si nous voulons faire un déploiement externe, nous sommes obligés d'aller la configuration de Opera (dossier utilisateur) et plus particulièrement le dossier widget et copier le widget correspondant que nous venons de créer pour le modifier à un endroit extérieur.

Parfais, mais maintenant y a t'il moyen de personnaliser ce widget pour le rendre compatible avec un site totalement externe de Opera ou encore ceux proposé par défaut sur le générateur ?
Là je dis à nouveau oui !

Lorsque nous analysons le widget, nous voyons qu'il a une configuration tout à fait classique :
  • un dossier JS : contenant les animations, les dates de mises à jour etc. en bref, le javascript qu'à besoin le widget pour fonctionner ;
  • un dossier SKIN : disposant des images, de la mise en forme générale et spécifique (via fichier CSS) ;
  • à la racine : le fichier CONFIG.XML, le fichier INDEX.HTML et un étrange fichier CONFIG.JS !

Ouvrons ce dernier dans notre éditeur de texte, nous obtenons simplement quelques renseignements complémentaires très utiles :
var skeletonConfig = {
feedURL : "http://my.opera.com/Groumphy/xml/atom/blog/",
feedTitle : "Carnet de Groumphy",
feedVersion : "generic",
maxItems : 9
};

Ainsi nous pouvons donc personnaliser le widget :
  1. feedURL est la variable déterminant le chemin vers le RSS,
  2. feedTitle est la variable permettant de gérer le titre du widget,
  3. feedVersion représente en terme de variable la forme qu'à le RSS ou ATOM,
  4. maxItems est simplement un nombre variable du nombre maximum d'item (entrée) générée par le widget.


Je n'ai pas encore essayé de le personnaliser, mais à première vue, toutes les autres fonctions contenues dans le dossier JS ne contiennent aucune variable personnalisable et font appels à ce fichier externe !

A suivre encore... Et encore !

Générateur de Widget

, , , ...

Faisant partie de la communauté de Opera, je ne vous présente plus les widgets, ces petits add-on que l'on déploie en deux et trois mouvements dans Opera à l'image de Firefox et ses extensions ou plugin.

Toutefois un lien que je tiens toutefois à donner avec grand plaisir est le générateur de Widget ! En effet, il est maintenant possible d'avoir un widget personnalisé au RSS de son site !

Il est implémenté directement dans toutes les pages de la communauté Opera (my.opera), mais maintenant il est possible de l'implémenter avec un générateur !

En 3 étapes vous avez votre widget permettant de lire votre flux RSS !
Le déploiement lui est un peu scabreux... Il se fait que par des liens via les serveurs Opéra.

Ce qui aurait été plus pratique aurait été un téléchargement du widget pour pouvoir avoir un déploiement externe et l'incorporer dans un site même externe.
Le widget n'aurais été téléchargeable que si le navigateur Opera était détecté... Mais avec une technologie client type javascript.

A suivre toutefois de prêt car certaines options sont encore masquées et permettraient d'avoir une certaine largesse d'esprit.
November 2009
M T W T F S S
October 2009December 2009
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