Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
1 septembre 2009 2 01 /09 /septembre /2009 00:00

Question classique :  je voudrais mettre une image de fond particulière sur un certain article . Variante plus raffinée :  En fait, je voudrais cette image sur certains articles, pas tous, et sans devoir préciser son url à chaque fois . Je dis  image de fond  pour fixer les idées, ce pourrait tout aussi bien être  une bordure particulière ,  une certaine police de caractères … tout ce que vous voudrez.

Cette question classique possède une réponse classique, sans JavaScript (chouette !), que j'expliquerai rapidement après avoir un peu causé de la structure d'un article de blog.

Cette réponse classique, excellente à tous points de vue, possède cependant quelques limites. Pour outrepasser ces limites, la petite cuisine que je propose (JavaScript, donc hélas niveau Privilège ou supérieur) peut rendre service. Elle complète donc la solution ancestrale plutôt qu'elle ne la remplace.

Comme d'habitude le tout sera nappé d'une épaisse sauce d'explications – car je suis cruel.


Anatomie d'un article

Un article est contenu dans un div de classe article. Ce div en contient à son tour entre deux et quatre autres :

  1. un div (facultatif) de classe option beforeArticle
  2. un div (toujours présent) de classe divTitreArticle
  3. un div (toujours présent) de classe contenuArticle
  4. un div (facultatif) de classe option afterArticle

Note : ce schéma n'est qu'une copie d'écran de l'inspecteur DOM de Firefox, vous obtiendriez la même information en consultant le code source d'une page (mais ce serait plus laborieux).

Les deux div de classe option (+ autre chose) contiennent la date, la signature et des liens :  publié dans  (catégorie de l'article), communauté, commentaires, etc. Ce contenu s'organise par le menu  Configurer  de l'admin OB.

Le menu  Publier  de cette même administration permet de préciser le texte de certains des éléments précédents (date, signature) et, évidemment, le titre de l'article et son contenu. La fenêtre principale de l'éditeur d'articles est, en somme, un outil à gérer le contenuArticle, ni plus ni moins.

La présentation de tout ceci se définit dans le(s) fichier(s) CSS du blog. Elle vaut pour tous les articles. Le  mode avancé  permet certes de distinguer les pages d'accueil des pages ordinaires mais pas de singulariser tel ou tel article.

À ce stade j'espère ne rien vous avoir appris…


La solution des grand-mères

Simple :  mon petit, puisque tu veux donner un fond à ton article et à lui seul, cuisine donc son contenuArticle. . Concrètement il faut utiliser le mode source (= le bouton  HTML ) de l'éditeur. Partons d'un texte d'article basique :

 Article de démonstration, avec un saut de ligne <br />juste pour montrer que je sais faire. 

Pour lui donner un style particulier (l'image de fond), emballons d'abord ce contenu dans un div :

 <div> Article de démonstration, avec un saut de ligne <br />juste pour montrer que je sais faire. </div> 
… ce qui ne change strictement rien à l'aspect visuel, puis, d'un geste inspiré, ajoutons à ce div tout neuf les indications de style requises :
 <div style="background-image:url(gnagnagna/patriiiiick.jpg)"> Article de démonstration, avec un saut de ligne <br />juste pour montrer que je sais faire. </div> 
(exemple emprunté à une fan de Patrick Bruel).

Cette manœuvre est expliquée dans divers coins du forum et des blogs d'aide (+1, donc).

Grand-maman improved

Guère plus compliqué :  puisque ta beeeelle photo doit resservir, n'encombre pas ton HTML d'indications de style, ne t'embête pas à copier/coller ces horreurs d'un article à l'autre, sois moderne et utilise une classe .

C'est-à-dire ? Que nous gardons le coup du nouveau div mais que ce div ne reçoit pas d'indications style="...", seulement une classe ad hoc :

 <div class="fanclub"> Article de démonstration, avec un saut de ligne <br />juste pour montrer que je sais faire. </div> 
… et cette classe se définit dans le CSS :
 .fanclub {background-image:url(gnagnagna/patriiiiick.jpg)} 

Les avantages sont connus :

  • la classe se définit en un seul exemplaire, même si elle concerne 50 articles. Le jour où on change de photo, ou bien celui où l'on ajoute une bordure, on fait la modif' une seule fois et les 50 articles suivent,
  • le HTML est moins verbeux : plus lisible, plus vite chargé dans le navigateur, etc.,
  • si vous utilisez plusieurs de ces classes leurs définitions sont regroupées en un endroit unique (le fichier CSS) au lieu d'être dispersées dans tout le blog. Plus commode pour choisir, non ?
  • bref : qu'est-ce que vous f…ez encore avec tous ces style="..." ?

Si cette solution vous suffit ne vous compliquez pas la vie avec la suite de l'article !


Grand-maman meets the big bad wolf

Notre nouveau div remplit complètement le contenuArticle. Cela signifie que la nouvelle décoration d'un certain article ne peut concerner que ce même contenuArticle. À la rigueur, pour que l'image de fond de ce certain article s'étende sous le bandeau inférieur, on peut tricher savamment en ajoutant un padding-bottom suffisamment important (3em, mettons) et un margin-bottom négatif opposé (-3em). M'enfin ça reste du bricolage casse-figure. Et si, toujours pour ce certain article, on veut changer la présentation du titre, celle des bandeaux ou celle de tout le div de classe article, on est bel et bien coincé.

Je vous rappelle tout de même que, si vous n'avez pas besoin de toucher au titre ni aux bandeaux, la solution de grand-mère, surtout dans sa variante à classe, est une très bonne solution. Elle marchera chez tous vos lecteurs même s'ils naviguent sans JavaScript, alors que ce qui vient est une pure bidouille JavaScriptienne, donc plus fragile.

Pourrez pas dire que je pratique la vente forcée…

Zorro rescues grand-maman

On garde l'idée d'utiliser  un machin  doté d'une classe spécifique : les classes, c'est bien. Mais cette classe spécifique on l'ajoute, grâce à un peu de magie noire, directement au div de l'article plutôt qu'à l'une de ses subdivisions.

Voilà l'idée. La prochaine section donne son mode d'emploi, la dernière (de lecture facultative) explique son fonctionnement si vous aimez comprendre.


Installation

Si vous n'avez jamais installé de JavaScript chez vous rendez-vous ici pour les détails.

Recopiez le programme suivant sur votre ordinateur :

 /* Jus de méninges - http://brendufat.over-blog.com/article-35453833.html */ /* Ajoute une classe à un article en partant de l'intérieur de l'article */ function marqueArticle(id,nc) {if (!id) return;if (!nc) return; for(var ref=document.getElementById(id);ref;ref=ref.parentNode) { if (!ref.className) continue; if ((/\barticle\b/).test(ref.className)) {ref.className+=' '+nc;return} } } 

Stockez ce programme, sans rien y changer, dans votre espace  Mes Documents/Autres fichiers  :

Ajoutez la ligne suivante à la fin de l'en-tête du blog :

 <script type="text/javascript" src="URL_du_programme"></script> 

Remplacez bien sûr URL_du_programme par l'url effective du fichier.

Ceci accompli, une fois pour toutes, vous êtes prêt à enrichir un article.

Mise en œuvre

Il faut modifier l'article en mode source. Il n'y a plus besoin de créer un nouveau div mais, où vous voudrez dans l'article, ajoutez une ligne similaire à celle-ci :

 <script id='id_du_script' type="text/javascript">marqueArticle('id_du_script','classe_nouvelle')</script> 

Explications :

  1. l' id_du_script est un identifiant à choisir par vous. Il figure deux fois dans la ligne, n'oubliez donc pas de l'écrire deux fois. Il doit être unique dans tout le blog, en prévision du cas où deux articles porteurs de ce genre de greffon se trouveraient sur une même page. Il n'a pas besoin de figurer dans le CSS.
  2. la classe_nouvelle, comme son nom l'indique, est la classe que vous ajoutez à l'article ( fanclub  dans notre exemple bruelesque).

Remarque : la  nouvelle classe  peut parfaitement être une liste de plusieurs noms de classes, séparés par des espaces, si cela vous rend service. Pourquoi pas fanclub patrick, fanclub michael et fanclub stockhausen (cherchez l'intrus) ? Libre à vous.

Comme dans la technique de grand-mère il faut ensuite ajouter la définition de cette ou ces classes nouvelle(s) dans le CSS pour voir un changement. Par exemple :

 /* le corps de l'article en plus gros*/ .article.fanclub .contenuArticle {font-size : 1.1em} /* le titre cadré à droite*/ .article.fanclub .divTitreArticle{text-align: right} /* image de fond selon le sujet */ .article.patrick {background-image:url(gnagnagna/patriiiiick.jpg)} .article.michael {background-image:url(gnagnagna/michaeeeeel.jpg)} .article.stockhausen {background-image:url(gnagnagna/doliprane.jpg)} 

Pour un exemple un peu plus sérieux cliquez sur le lien (en haut à droite)  Le pourquoi du Comment . Il vous conduira à la table des matières de cette rubrique. Vous verrez qu'on ne peut pas commenter cette table (ça, c'est une case à cocher dans l'admin) et qu'on ne peut pas non plus la recommander (et ça, c'est l'application de la présente technique : le lien  recommander  est en display:none pour cette table).

Dernière remarque : puisqu'il s'agit de JavaScript rappelez-vous que vos lecteurs naviguant sans JS verront des articles tout à fait ordinaires. Si donc vous ne voulez changer de présentation que pour le corps de l'article, écoutez plutôt grand-mère.


Encore une fois : pas besoin de lire cette partie pour utiliser le programme. Mais si le  comment ça marche  vous intéresse…

Dissection

 function marqueArticle(id,nc) { // Vérification des arguments - abandon en cas d'absence if (!id) return;if (!nc) return; // Boucle de remontée dans l'arborescence for(var ref=document.getElementById(id);ref;ref=ref.parentNode) { // élément sans classe : on continue if (!ref.className) continue; // élément de classe article : on traite et on termine if ((/\barticle\b/).test(ref.className)) {ref.className+=' '+nc;return} // élément de classe non-article : rien à faire, la boucle continue } // Arriver ici est une anomalie : article non trouvé } 

Le fichier ne contient qu'une fonction qu'on appellera ensuite depuis l'intérieur de l'article. Pour que cet appel fonctionne il faut que la fonction soit déjà définie, voilà pourquoi le programme est à inclure dans l'en-tête du blog plutôt que son pied (où il arriverait après les articles, donc trop tard).

Cette fonction demande deux arguments : un identifiant (attaché à l'élément script présent dans l'article) et la classe (ou liste de classes) qu'on souhaite ajouter à l'article.

Après deux tests simples de validation des arguments on s'engage dans le traitement proprement dit : une boucle qui commence à l'élément porteur de l'id indiqué (donc, normalement, le script qui appelle la fonction) et qui remonte de parent en parent, en testant la classe éventuelle de ce parent. Si on trouve un élément de classe article, on lui ajoute la nouvelle classe et on sort de la fonction (return).

En cas d'anomalie (id mal recopié, blog esquinté…) la boucle remonte jusqu'à la racine du document et se termine : pas de traitement mais pas de plantage non plus. On peut mettre une alerte avant la dernière accolade si on juge utile de paniquer le lecteur.

Petite discussion critique

Rien donc de très bouleversant : on circule dans l'arborescence à la recherche d'un élément doté de certaines caractéristiques (classe) puis on le traite. Le seul point délicat était de savoir où faire commencer la recherche.

J'aurais bien voulu me dispenser de l'identifiant auxiliaire, dont je sens bien qu'il est une source d'erreurs parce qu'écrit deux fois, mais je n'ai pas trouvé d'autre moyen pour faire savoir au script d'appel  où il se trouvait  dans le document. Il n'existe pas de GPS pour les scripts…

Dans un cas comme celui-ci, en effet, le mot-clé this désigne tout le document et pas l'élément où l'on se trouve. Ce mot-clé ne désigne l'élément où l'on se trouve que s'il figure dans un gestionnaire d'événements. Alors pourquoi ne pas essayer ? Oui, mais quel événement employer ? Pas question de demander de cliquer dans l'article pour en faire changer l'aspect ! Le seul événement utilisable serait onload : à la fin du chargement de, par exemple, un span situé en début d'article, on lancerait la fonction. Très ingénieux, malheureusement l'événement onload n'est disponible que pour la page dans son ensemble, qu'on l'attache à body ou à document. Résumé : coincé.

Et voilà pourquoi il faut donner un identifiant à l'élément script puis écrire à nouveau cet identifiant pour appeler la fonction. Dommage… Cela dit, ça marche très bien et c'est l'essentiel !

commentaires

<br /> <br /> bon ça ne marche pas mais je pense que c'est parce que c'est du JS<br /> <br /> <br /> les lignes se transforment:<br /> <br /> <br /> // <br />  for(var ref=document.getElementById('UN_ID_UNIQUE');ref;ref=ref.parentNode) {if (!ref.className) continue; if ((/barticleb/).test(ref.className)) {ref.className+=' '+'NEWCLASS';break}}<br /> // ]]><br /> <br /> <br /> le data sort de je ne sais où ? je crois q'il faut attendre la fin du bug<br /> <br /> <br /> <br />
Répondre
A
<br /> <br /> "livre d'or" n'est pas un bon identifiant : apostrophe et espace, ça fait deux grosses arêtes à avaler ! livre_d_or serait meilleur.<br /> A retenir : pour être tranquille, ne compose tes identifiants et noms de classes qu'avec les lettres, les dix chiffres, l'underscore et rien d'autre. Ne commence pas par un chiffre.<br /> <br /> <br /> il faut aussi penser à remplacer UN_ID_UNIQUE par, justement, livre_d_or<br /> <br /> <br /> le CDATA ajouté automatiquement l'a toujours été et il ne doit pas t'inquiéter : précaution envers les navigateurs qui ne comprennent pas le JS (il y en a)<br /> <br /> <br /> <br />
<br /> <br /> non je n'ai pas compris ce que je devais mettre comme phrase dans le CSS avec newclasse ?<br /> <br /> <br />  <br /> <br /> <br /> tu as l'air pessimiste avec le java script ! as tu des nouvelles autres que celles du forum ? c-a-d : rien !  ?    <br /> <br /> <br /> <br />
Répondre
A
<br /> <br /> 1-NEWCLASS n'est qu'un mot choisi par moi, à remplacer par un truc à ton goût. Supposons que tu prennes 'peinture'. Alors l'article sera doté, en plus de la classe 'article' qu'il possède par<br /> principe, de la classe 'peinture' ajoutée par toi.<br /> <br /> <br /> Utilisation : si ds le CSS tu as déjà<br /> <br /> <br /> .article {background-image:url(image_generale.jpg);}<br /> <br /> <br /> tous les articles ont pour fond image_generale.jpg. Si tu ajoutes, après cette ligne, qqchose comme<br /> <br /> <br /> .peinture {background-image:url(picasso.jpg);}<br /> <br /> <br /> l'article 'traité' aura comme image de fond picasso.jpg au lieu de l'image générale. Ca se décante, là ?<br /> <br /> <br /> 2-javascript : non, je ne suis pas spécialement pessimiste, le souci actuel sera corrigé. Simplement nous sommes lundi de Pâques et j'ai préféré te fournir une solution immédiatement utilisable<br /> :-)<br /> <br /> <br /> D'ailleurs je pourrais l'incorporer à l'article, maintenant que j'y pense...<br /> <br /> <br />  <br /> <br /> <br />  <br /> <br /> <br /> <br />
<br /> <br /> heu bug sur le forum je ne peux plus répondre à mon topic ; en fait ce que je voudrais c'est quand je rajoute des fonds ponctuels juste pour un article ce fond couvre le titre et la zone "ajouter<br /> des commentaires" car pour l'instant j'obtiens 2 fonds différents sur un seul article ça ne fait pas forcément joli voir ici en exemple<br /> <br /> <br /> http://mademoiselle-biotupp.over-blog.com/article-petit-article-du-soir-47891830.html  ce que je voudrais c'est ne plus voir ponctuellement le fond marron craquelé mais<br /> je sais pas si c'est possible je n'ai compris qu'en partie l'article çi-dessus ....<br /> <br /> <br />  <br /> <br /> <br /> pour mon autre question c'était ici: http://brendufat.over-blog.com/article-30941115-6.html#anchorComment<br /> <br /> <br />  <br /> <br /> <br /> merci de ton aide bizzz<br /> <br /> <br /> <br />
Répondre
A
<br /> <br /> Là c'est très clair! :-)<br /> <br /> <br /> Pour que ce fond "ponctuel" couvre tout l'article, y compris le titre et le pied d'article, il te faut la solution à base de JS. Comme cette solution emploie un fichier externe, et comme le bug<br /> actuel de l'éditeur OB en empêche l'emploi, il faut que je te bricole une solution sans fichier externe, solution que voici :<br /> <br /> <br />  <br /> <br /> <br /> <br /> for(var ref=document.getElementById('UN_ID_UNIQUE');ref;ref=ref.parentNode)<br /> {if (!ref.className) continue;<br /> if ((/barticleb/).test(ref.className)) {ref.className+=' '+'NEWCLASS';break}}<br /> <br /> <br /> <br />  <br /> <br /> <br /> Copie ces cinq lignes plutôt au début de ton article, en mode source.<br /> <br /> <br /> Remplace UN_ID_UNIQUE par un identifiant de ton choix (inspiré du titre de l'article, p ex. N'hésite pas à faire long, cet identifiant ne resservira nulle part ailleurs)<br /> <br /> <br /> Remplace NEWCLASS par un nom de classe de ton choix lui aussi. C'est ce nom qui te servira dans le CSS pour modifier le style de cet article (et celui des éventuels quelques autres où tu auras<br /> répété cette manip, avec le même NEWCLASS et d'autres identifiants).<br /> <br /> <br /> Est-ce clair ?<br /> <br /> <br /> <br />
<br /> <br /> bonsoir bren ! javais pas vu ton petit bateau favicon ! c'est nouveau ? c'est trop mignon :-)<br /> <br /> <br /> j'ai plusieurs questions; la première à propos de cet article (que je n'avais pas vu et qui m'aurait éviter bien des bidouilles m'enfin ça me fait avancer....pour plus de clareté il faut lire mon<br /> dernier post sur le forum ici http://forum.over-blog.com/thread-2685406-99999.html<br /> <br /> <br />  <br /> <br /> <br /> ma 2 eme question ...je vais chercher sur ton site et si je trouve pas je recom hihi<br /> <br /> <br /> au fait je n'ai pas oublié l'option "au hasard" c'est classé dans "mes trcus à faire" :-)<br /> <br /> <br /> <br />
Répondre
A
<br /> <br /> Le petit bateau est là depuis très longtemps... :-)<br /> <br /> <br /> Pour la 1ère question j'ai tenté de répondre sur le forum, pour la 2e il faut sans doute me reporter à ton autre commentaire ?<br /> <br /> <br /> <br />

Archives