En pratique
Le principe est de rendre AJAX abordable car la complexité est cachée :
J’ai un morceau de page qui contient des liens vers cette même page et
ne provoquent de changement que dans le morceau de page considéré :
- je mets ce morceau de page dans un squelette séparé
- je marque les liens concernés par la class ajax :
<a href='monlien' class='ajax'>...</a>
- j’inclus mon squelette dans la page principale avec
<INCLURE{fond=monskel,ajax,env}>
ou
#INCLURE{fond=monskel,ajax,env}
Et c’est tout !
Quelques petites précisions tout de même :
- testez toujours d’abord votre squelette sans l’argument
{ajax}
; -
{ajax}
devrait toujours être accompagné de{env}
afin d’éviter tout risque d’injection d’urls dans le cache de SPIP ; - par defaut, les liens
a
contenus dans une classepagination
sont aussi ajaxés ; - il est possible de cibler d’autres liens en spécifiant leurs sélecteurs CSS jquery dans la variable javascript
ajaxbloc_selecteur
. Exemple :var ajaxbloc_selecteur = 'a.ajax, a.uneautreclasse';
; - il faut bien entendu que
#INSERT_HEAD
figure dans le head du squelette de la page, et que le javascript soit activé dans le navigateur de l’internaute qui la consulte.
En détail
Syntaxe d’appel :
<INCLURE{fond=mon_fond,ajax,env}>
ou
[(#INCLURE{fond=mon_fond,ajax,env})]
Cet appel inclut le squelette mon_fond en « ajaxant » automatiquement tous les liens ciblés par la variable js ajaxbloc_selecteur
.
Un bloc <div ..></div>
est inséré automatiquement autour du contenu du squelette inclus, pour le mécanisme de gestion de l’ajax.
Par défaut celle-ci cible les sélecteurs CSS .pagination a, a.ajax
. Autrement dit, il faut avoir dans le code source des squelettes :
- soit la gestion standard de la pagination par SPIP. A condition que la balise
#PAGINATION
soit inclue dans un élément de classepagination
. Ex :<p>#PAGINATION</p>
- soit une classe
ajax
sur les liens (<a class="ajax" href=...>
)
Le hit ajax relance automatiquement le calcul du squelette inclus seul en restaurant son #ENV
, et en y ajoutant les paramètres passés dans l’url du lien
Le bloc rechargé passe en opacité 50 % et prend la class loading
pendant le chargement ce qui permet de le styler à sa convenance.
Il est intéressant de noter que :
- les liens
ajax
sont mis en cache dans le navigateur lorsqu’ils sont cliqués une fois. Le bloc n’est donc chargé qu’une fois, même si l’internaute revient plusieurs fois sur le lien concerné - certains liens peuvent être pré-chargés à l’avance en leur ajoutant la classe
preload
Quelques exemples
Utilisation de liens ajax
Soit le squelette inc-liens.html
Il sera appelée dans le squelette incluant par
[(#INCLURE{fond=inc-liens,ajax,env})]
Et contiendra
<BOUCLE_liste(AUTEURS) >
<a class="ajax" href="[(#SELF|parametre_url{id_auteur,#ID_AUTEUR})]">
#NOM #ID_AUTEUR
</a>
</BOUCLE_liste>
[(#ENV{id_auteur}|oui)
#ENV{id_auteur}
]
Utilisation de la pagination
Pour la pagination, prenons un exemple tiré de squelettes-dist/sommaire.html
.
Mettons dans un squelette inc-recents.html
la boucle qui liste les articles récents :
[(#REM) Derniers articles ]
<B_articles_recents>
<div class="menu articles">
[(#ANCRE_PAGINATION)]
<h2><:derniers_articles:></h2>
<ul>
<BOUCLE_articles_recents(ARTICLES) {par date}{inverse} {pagination 5}>
<li class="hentry">
[(#LOGO_ARTICLE_RUBRIQUE|#URL_ARTICLE|image_reduire{150,100})]
<h3 class="entry-title"><a href="#URL_ARTICLE" rel="bookmark">#TITRE</a></h3>
<abbr class="published"[ title="(#DATE|date_iso)"]>[(#DATE|affdate_jourcourt)]</abbr>[, <:par_auteur:> (#LESAUTEURS)]
[<div class="#EDIT{intro} introduction entry-content">(#INTRODUCTION)</div>]
</li>
</BOUCLE_articles_recents>
</ul>
[<p class="pagination">(#PAGINATION)</p>]
</div>
</B_articles_recents>
Il suffit alors de mettre dans sommaire.html, à la place de cette boucle
<INCLURE{fond=inc-recents,ajax,env}>
Limites et cas particuliers
Ce mécanisme automatisé d’ajaxisation des blocs repose sur une hypothèse : par défaut, un lien ajax ne permet de rafraîchir que le bloc le contenant, en insérant la version modifiée au même endroit. À noter qu’il est possible, à partir d’un bloc, de recharger un autre bloc de la page, en utilisant la technique décrite plus bas.
Par ailleurs, il est important de noter que le calcul du squelette inclus ne doit reposer exclusivement que sur les paramètres passés en #ENV
. En effet, lors du calcul du bloc ajax, celui-ci sera recalculé tout seul, en dehors du squelette appelant. Seules les variables contenues dans #ENV
seront restaurées.
Ainsi, il n’est pas possible de faire référence à des variables php globales : celles-ci ne seront pas restaurées au moment du calcul du bloc ajax. Si vous vouliez vraiment utiliser des variables globales php, il faut les réinjecter dans le #ENV
au moment de l’inclusion :
<INCLURE{fond=monskel,ajax,env,parametre=#EVAL{$GLOBALS['toto']}}>
Modalités complémentaires
SPIP 3.0 améliore le mécanisme :
Historique de navigation
Les liens .ajax
ne cassent plus l’historique de navigation sur les navigateurs qui supportent l’API HTML5 History (Firefox, Safari, Chrome à la date de cet article). C’est-à-dire que lorsqu’on clique sur un lien ajax de SPIP qui recharge une partie de la page, l’URL est mise à jour dans le navigateur et le visiteur peut cliquer sur Précédent pour revenir en arrière.
Classes spéciales sur les liens ajax
-
.nohistory
indique que le lien n’affecte pas l’historique de navigation lorsqu’il est cliqué ; -
.preload
indique à SPIP que le contenu du lien ajax doit être préchargé au moment où la page est chargée. Ainsi le clic sur le lien produira une mise à jour immédiate ; -
.nocache
indique à SPIP que le contenu du lien ajax ne doit pas être mis en cache. Ainsi plusieurs clics sur le même lien provoqueront autant de chargements depuis le serveur (par défaut, seul le premier chargement à lieu pour une url donnée et le contenu est ensuite mémorisé par le navigateur).
#BOUTON_ACTION
Les #BOUTON_ACTION
peuvent déclencher le rechargement du bloc incluant en ajax.
Rechargement télécommandé de blocs ajax
Les liens .ajax
permettent par défaut le rechargement du bloc ajax qui les contient, mais il est parfois nécessaire de provoquer le rechargement d’un autre bloc ajax de la page.
Pour cela, il devient possible, au moment de leur inclusion, de nommer les blocs ajax qui doivent pouvoir être rechargés :
<INCLURE{fond=...,ajax=nomdubloc} />
Le bloc ajax ainsi nommé peut ensuite être rechargé via l’appel de ajaxReload('nomdubloc')
.
Il est possible de passer en second argument une liste d’options contenant :
-
callback
: fonction callback qui doit être appelée après le chargement ajax du bloc
-
args
: liste d’argument qui seront passés à l’url lors du chargement du bloc (permet de modifier le #ENV du bloc mis à jour) ;
-
history
: indique si le rechargement affecte ou non l’historique de navigation (faux par défaut).
Exemple
ajaxReload('nomdubloc', {
callback:function(){alert('fini');},
args:{id_article:3},
history:false
});
ajaxReload peut être utilisé également sur un sélecteur jQuery auquel cas il provoquera le rechargement du plus petit bloc ajax qui contient l’élément ciblé. Il ne prend alors qu’un argument possible (le tableau d’options) :
$('#contenu').ajaxReload({args:{id_article:3}})
Voir aussi
- <INCLURE> d’autres squelettes
- Ajax dans un #BOUTON_ACTION
- Documentation "Blocs-ajax-et-ajaxReload" sur programmer.spip.net
- AjaxReload par l’exemple
et Exemple de bloc télécommandé en Ajax sur contrib.spip.net