This article discusses how to sort the articles on our site in several different manners, depending on which section the articles are in and how each section is presented to the site visitor:
- in some sections, the articles are logically published one after the other, and we therefore want them displayed in chronological order with the most recent at the top of the list and the oldest at the bottom.
- in other sections, we want to control the order of articles displayed on the public site by specifically numbering them ("1. The first article", "2. The second article", etc.).
- and finally, there are a few sections where articles should be displayed in chronological order as above, with a few exceptions which should be displayed before any others in a specific sequence.
For the purposes of the rest of this article, we assume that our code loops are nested in side a section loop, (e.g. the "rubrique.html" page):
<BOUCLE_main_section(RUBRIQUES){id_rubrique}>
...
</BOUCLE_main_section>
These effects can be achieved as follows:
There are several methods to accomplish these sorts. Note that the two methods presented below are just as valid for sorting articles as they are for other SPIP objects, like sections, news items, etc.
The simple method
Reminder: To sort articles according to an imposed order, their titles are numbered in the private zone with a numeral followed by a full stop and a blank space: "1. First article", "2. Second article", etc.
Within the squelette template files, it is possible to not show these sorting numbers on the public site by applying the |supprimer_numero
filter to the #TITRE
tag, and using the {par num titre}
criteria on the ARTICLES loop to sort the records according to the numbers indicated.
To sort according to an imposed order AND/OR according to the date, we would then code this as (inside a RUBRIQUES loop):
<BOUCLE_articles(ARTICLES) {id_rubrique} {par num titre}{!par date}>
[(#TITRE|supprimer_numero)]
</BOUCLE_articles>
The articles in the section will all be sorted by their assigned numbers (in the titles), and any that have the same such number will be sorted in inverse date order.
Important note: This works perfectly well so long as, for a given section, either all of the articles are numbered or none of them are. On the other hand, if a section contains un-numbered articles, except for just one that is numbered, then that single one will be displayed last in the list. In fact, un-numbered, the articles are all considered as having zero as their sorting number. To avoid this sorting affect, we then need to use the following more refined method.
Fine-tuned method
Inside our RUBRIQUES loop, we’re going to perform the following test: within this section, is there at least one article with a title that starts with a number followed by a full stop?
<BOUCLE_number_test(ARTICLES){id_rubrique}{titre==^[0-9]+\.}{0,1}>
There is at least one numbered article in this section.
</BOUCLE_number_test>
There are no numbered articles in this section.
<//B_number_test>
The interesting criterion here is this one:
{titre==^[0-9]+\.}
This selects an article by title
according to a regular expression which looks for titles with one or more numbers (in the range 0 to 9) immediately following by a dot, at the beginning of the title. The syntax is as follows: ==
indicates selection by regular expression; ^
indicates the beginning of the string to be tested; "[0-9]
" means "the range of characters between 0 and 9 inclusive"; +
indicates at least one (and optionally more) of the preceding characters; and \.
indicates the dot character.
Note, this only selects one such numbered article ({0,1}
); this way, the inside of the loop is only executed once. Moreover, even if there is only one numbered article it will still cause the list to be displayed in "numbered" order.
The above loop displays the message "There is at least one numbered article in this section." if the section contains at least one article with a title which begins with a number, otherwise it displays "There are no numbered articles in this section."
These messages can now be replaced with nested loops which will display the articles in the desired presentation order:
<ul>
<BOUCLE_number_test(ARTICLES) {id_rubrique} {titre==^[0-9]+\.} {0,1}>
<BOUCLE_number_order(ARTICLES) {id_rubrique} {par num titre}>
<li>[(#TITRE|supprimer_numero)]</li>
</BOUCLE_number_order>
</BOUCLE_number_test>
<BOUCLE_date_order(ARTICLES) {id_rubrique} {par date}{inverse}>
<li>#TITRE</li>
</BOUCLE_date_order>
<//B_number_test>
</ul>
The numbered articles in the section are then displayed first, sorted by number, and then followed by those that don’t have any number, sorted most recent first to oldest last.
Or even more simply:
<BOUCLE_Sorting(ARTICLES){par num titre, titre}>
<li>[(#TITRE|supprimer_numero)]</li>
</BOUCLE_Sorting>
Which will sort the articles in order of title and then by number.