In practice
The idea is to make AJAX easy and to hide its complex workings.
Suppose that on a page there are links to that same page, and clicking on them causes a change only in a certain zone of the page. For this to be possible:
- place the part of the page in question in a separate template
- mark the links which call that template with the class ajax e.g.
<a href='mylink' class='ajax'>...</a>
- include the template in the main page with:
<INCLURE{fond=mytemplate}{ajax}{env}>
or
#INCLURE{fond=mytemplate}{ajax}{env}
And that’s all!
Just a few additional words of advice:
- Always start by testing your template without the
{ajax}
criterion. - To avoid any risk of URLs being injected into SPIP’s cache, the
{ajax}
criterion should always be accompanied by{env}
. - Hyperlinks contained within a
pagination
class are automatically ajaxed by default. - It is possible to apply the ajax criterion to other classes by specifying the jQuery selector
var ajaxbloc_selecteur = 'a.anotherclass';
In detail
Calling syntax:
<INCLURE{fond=my_template}{ajax}{env}>`
or
[(#INCLURE{fond=my_template}{ajax}{env})]
This call includes my_template while automatically "ajaxing" all the links targeted by the javascript variable ajaxbloc_selecteur
.
The ajax managing process automatically inserts a <div ..></div>
block around the content of the included template.
By default, ajax is applied to the classes .pagination a
and a.ajax
. In other words, in the template you need to have either:
- the standard SPIP pagination with the
#PAGINATION
tag within an element with the classpagination
. For example,<p class="pagination">#PAGINATION</p>
. - or an
ajax
class on hyperlinks (<a class="ajax" href=...>
).
A click on the ajax link recalculates just the included template, restoring its #ENV
and adding the parameters which have been passed in the URL of the link.
The reloaded block takes an opacity of 50 % and adopts the class loading
as it is being loaded, which enables you to give it the style you wish.
It is good to note that:
- ajax links are cached by the browser when they are first clicked. Thus the block is only loaded once, even if the visitor clicks several times on the link;
- blocks may be preloaded by placing the class
preload
on the link.
Some examples
Using ajax links
A inclusion in the containing template such as [(#INCLURE{fond=inc-links}{ajax}{env})]
would call the template inc-links.html
, which could contain the following code:
<BOUCLE_list(AUTEURS)>
<a class="ajax" href="[(#SELF|parametre_url{id_auteur,#ID_AUTEUR})]">
#NOM #ID_AUTEUR
</a>
</BOUCLE_list>
[(#ENV{id_auteur}|oui)
#ENV{id_auteur}
]
Using pagination
For pagination, let’s take an example from squelettes-dist/sommaire.html
.
Put in a template inc-recents.html
the loop which lists recent articles:
[(#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>
<small><abbr class="published"[ title="(#DATE|date_iso)"]>[(#DATE|affdate_jourcourt)]</abbr>[, <:par_auteur:> (#LESAUTEURS)]</small>
[<div class="#EDIT{intro} introduction entry-content">(#INTRODUCTION)</div>]
</li>
</BOUCLE_articles_recents>
</ul>
[<p class="pagination">(#PAGINATION)</p>]
</div>
</B_articles_recents>
Now in sommaire.html
, in place of this code, you can put:
<INCLURE{fond=inc-recents}{env}{ajax}>
Limits and particular cases
This "ajaxing" mechanism only allows you to reload the block which contains the link in question, inserting the new block in the same place. You cannot target another area of the page.
It is also important to realise that the calculation of the template relies exclusively on the parameters passed through #ENV
. For, when the ajax block is calculated, this is done outside of the calling template. Only the variables passed by #ENV
are available.
This means that global PHP variables cannot be referenced either: they are not available when the ajax block is being calculated. If you must use PHP global variables, then you need to re-inject them into #ENV
when you make the inclusion:
<INCLURE{fond=mytemplate}{ajax}{env}{myparameter=#EVAL{$GLOBALS['toto']}}>
Additional modalities
SPIP 3.0 improves mecanism:
Navigation history
Ajax links no longer break the browsing history on browsers that support the HTML5 History API (Firefox, Safari, Chrome at the date of this article). This means that when a SPIP ajax link is clicked which reloads part of the page, the URL is updated in the browser and the visitor can click on Back to go back.
Special classes on ajax links
-
.nohistory
indicates that the link does not affect the browsing history when clicked ; -
.preload
tells SPIP that the content of the ajax link must be preloaded when the page is loaded. Thus clicking on the link will produce an immediate update; -
.nocache
tells SPIP that the ajax link content should not be cached. Thus several clicks on the same link will cause as many loads from the server (by default, only the first load takes place for a given url and the content is then stored by the browser).
#BOUTON_ACTION
The #BOUTON_ACTION
can trigger the reload of the block including ajax.
Remote reloading of ajax blocks
The .ajax
links allow by default the reloading of the ajax block which contains them, but it is sometimes necessary to cause the reloading of another ajax block of the page.
To do this, it becomes possible, at the time of inclusion, to name the ajax blocks that should be reloadable:
<INCLURE{fond=...,ajax=nomdubloc} />
The named ajax block can then be reloaded via the ajaxReload('blockname')
call.
It is possible to pass as a second argument a list of options containing :
-
callback
: callback function which should be called after ajax loading of the block
-
args
: list of arguments which will be passed to the url when the block is loaded (allows to modify the #ENV of the updated block) ;
-
history
: indicates if the reloading affects or not the browsing history (false by default).
Example
ajaxReload('nomdubloc', {
callback:function(){alert('fini');},
args:{id_article:3},
history:false
});
ajaxReload can also be used on a jQuery selector, in which case it will cause the reload of the smallest ajax block that contains the targeted element. It then takes only one possible argument (the options array):
$('#content').ajaxReload({args:{item_id:3}})
See also
- Documentation "Blocks-ajax-and-ajaxReload" on programmer.spip.net
- AjaxReload by example
and AjaxReloaded block example on contrib.spip.net