JaliosXperience
fr en
Link

Pager, contexte et request

Nicolas Plessis - on 1/20/09 at 7:32 PM

Bonjour,

Je rencontre un problème lors de l'utilisation du pager JCMS 6 lorsque je souhaite utiliser des gabarits "query" dans une recherche.

Voici un morceau choisi du code que j'utilise dans ma portlet listant les résultats d'une recherche :

<jalios:foreach name="itPub" type="Publication"
    collection="<%= resultSet %>" max="<%= pagerHandler.getPageSize() %>"
    skip="<%= pagerHandler.getStart() %>">
  <jalios:include pub="<%= itPub %>" usage="query" />
</jalios:foreach>
<jalios:pager name="pagerHandler" />

Lorsque j'affiche la portlet pour la première fois tout se passe bien, j'ai les 10 premiers résultats et un pager qui s'affiche en dessous. Lorsque je tente d'utiliser le pager, plus rien ne fonctionne, la page de résultat affiche toujours la même publication, la 10e, autrement dit la dernière qui s'est "affichée correctement" (si je fixe le pageSize du pager à 20 pages, c'est la 20e qui s'affiche en boucle).

Il semblerait que la requête ou les attributs de requête passés via Ajax ne soient pas les bons d'après une tentative de debugage ; car il me semble que le tag jalios:include met la publication à afficher en attribut de requête (du moins le

custom/jcms/doResultDisplay.jsp

la récupère ainsi).

Si maintenant je modifier mon code ainsi :

<jalios:foreach name="itPub" type="Publication"
    collection="<%= resultSet %>" max="<%= pagerHandler.getPageSize() %>"
    skip="<%= pagerHandler.getStart() %>">
  *<%= itPub.getTitle() %><br/>*
</jalios:foreach>
<jalios:pager name="pagerHandler" />

Tout fonctionne normalement (mais bon, ce n'est pas le résultat attendu, je ne peux pas me permettre de copier mes gabarits résumés dans toutes mes portlets de résultats de recherche)

Avez-vous une idée pour corriger ce problème ?

Merci.

Olivier Jaquemet - on 1/21/09 at 9:16 AM

Bonjour Nicolas,

Ce que semble indiquer ton second essai avec le <% itPub.getTitle() %>, qui fonctionne, c'est que le pager fonctionne bien, que la variable itPub est correcte, mais que si tu utilise un <jalios:include usage="query"/> cela ne fonctionne pas.

La mécanique de rafraîchissement ajax-refresh conserve le plus d'élément possible du contexte d'exécution original de la portlet, cela comprend également l'usage courant du gabarit de la porlet. Peut être que celui ci-vient interférer avec l'usage "query" que tu essai de forcer pour ton jalios:include. pourrais tu essayer différente combinaison de l'attribut usage :

Si tu ne met rien, que se passe-t-il?

  <jalios:include  pub='<%= itPub %>'/>

Au cas ou il s'agisse d'un problème de tag pooling de ton serveur d'appli :

  <jalios:include  pub='<%= itPub %>' usage='<%= "query" %>'/>

Nicolas Plessis - on 1/21/09 at 2:37 PM

Bonjour Olivier,

J'ai essayé tes deux propositions mais le résultat est le même malheureusement.

J'ai testé par ailleurs ce code :

<jalios:foreach name="itPub" type="Publication"
    collection="<%= resultSet %>" max="<%= pagerHandler.getPageSize() %>"
    skip="<%= pagerHandler.getStart() %>">
  <%
  Integer itPublicationCounter = new Integer(pagerHandler.getStart() + itCounter);
  request.setAttribute("counter", "" + itPublicationCounter);
  %>
  <jalios:include pub="<%= itPub %>" usage="query" />
</jalios:foreach>
<jalios:pager name="pagerHandler" />

Le résultat est surprenant puisque l'attribut "counter" est bien récupéré par le resultDisplay, quand je change de page mes numéros de résultat s'incrémentent comme il le faut. La publication reste fausse en revanche.

J'ai alors testé cette version :

<jalios:foreach name="itPub" type="Publication"
    collection="<%= resultSet %>" max="<%= pagerHandler.getPageSize() %>"
    skip="<%= pagerHandler.getStart() %>">
  <%
  Integer itPublicationCounter = new Integer(pagerHandler.getStart() + itCounter);
  request.setAttribute("counter", "" + itPublicationCounter);
  request.setAttribute(PortalManager.PORTAL_PUBLICATION, itPub);
  %>
  <jalios:include pub="<%= itPub %>" usage="query" />
</jalios:foreach>
<jalios:pager name="pagerHandler" />

Elle ne fonctionne pas non plus.

Mon dernier essai, trouvé de façon hasardeuse fonctionne à 100% en revanche :

<jalios:foreach name="itPub" type="Publication"
    collection="<%= resultSet %>" max="<%= pagerHandler.getPageSize() %>"
    skip="<%= pagerHandler.getStart() %>">
  <%
  Integer itPublicationCounter = new Integer(pagerHandler.getStart() + itCounter);
  request.setAttribute("counter", "" + itPublicationCounter);
  ServletUtil.backupAttribute(pageContext, PortalManager.PORTAL_PUBLICATION);
  %>
  <jalios:include pub="<%= itPub %>" usage="query" />
  <%
  ServletUtil.restoreAttribute(pageContext, PortalManager.PORTAL_PUBLICATION);
  %>
</jalios:foreach>
<jalios:pager name="pagerHandler" />

Mais je ne comprends pas vraiment pourquoi ça fonctionne.

Jean-Phillipe Encausse - on 1/21/09 at 3:13 PM

Bonjour,

Quelques pistes:

1. Je suppose qu'il n'y a pas de cache sur la portlet ?

2. Est ce que les PortletsQueryForeach fonctionnent avec le gabarit présentant les résultats (doPortletQueryForeachResults.jsp) ?

<%@ include file='/jcore/doInitPage.jsp' %>
<%@ include file='/jcore/portal/doPortletParams.jsp' %>
<% 
  PortletQueryForeach box = (PortletQueryForeach) portlet;
  jcmsContext.setTemplateUsage(TypeTemplateEntry.USAGE_DISPLAY_QUERY);  
%>
<%@ include file='doQuery.jsp' %>
<%@ include file='doSort.jsp' %>
<%@ include file='doForeachHeader.jsp' %>
		<jsp:include page='<%= "/"+itPub.getTemplatePath(jcmsContext) %>' flush='true' />
<%@ include file='doForeachFooter.jsp' %>
<%@ include file='doPager.jsp' %>

Le principe est :

  • de positionner l'usage (Le même pour tous)
  • de positionner la publication (doForeachHeader.jsp)
  • d'inclure le gabarit d'affichage

C'est ce que fait le tag <jalios:include> automatiquement.

3. Reprenons le scénario:

  • Tu affiches la page (10 résultats de recherche)
  • Tu clique sur la page 2 du pager
  • Le 10eme résultat s'affiche et les autres clics ne fonctionnent pas

Quelques questions:

  • Lors du rafraichissement de la page est ce que tout revient à la normal ?
  • Lors du clic est ce que un carre rouge apparait en haut à droite ?
  • Pour les clics suivants ?
  • Est ce qu'il y a des erreurs JavaScript ?
  • Est ce que le gabarit de la Skin de la Portlet contient bien les outter css (dans la source il doit y avoir class="ID_c_1234 ... Ajax-Refresh-Div"

J'ai l'impression que la page 2 est forcé comme si le getUrlWithUpdatedParams() contenait ton paramètre.

Nicolas Plessis - on 1/21/09 at 3:29 PM

Bonjour Jean-Philippe,

Voici mes réponses :

1. En effet pas de cache positionné par mes soins.

2. Je viens de créer une portlet QueryForeach de base ramenant mon type de contenu et utilisant le gabarit de résultat et elle fonctionne normalement. Note que mon gabarit résumé est celui de base, je ne l'ai pas encore modifié, cela viendra plus tard.

Avant de répondre à tes dernières questions, je préfère préciser mon problème.

En arrivant sur ma portlet je vois en simplifiant (pageSize = 5):

1. Titre Résultat 1
2. Titre Résultat 2
3. Titre Résultat 3
4. Titre Résultat 4
5. Titre Résultat 5

Si je clique sur la page 2 j'obtient :

6. Titre Résultat 5
7. Titre Résultat 5
8. Titre Résultat 5
9. Titre Résultat 5
10. Titre Résultat 5

Si je reclique sur la page 1 toujours dans le pager j'obtient :

1. Titre Résultat 5
2. Titre Résultat 5
3. Titre Résultat 5
4. Titre Résultat 5
5. Titre Résultat 5

Voici mes réponses :

  • Lors du rafraichissement de la page est ce que tout revient à la normal ?
    • Oui, je retombe sur la premier page et elle s'affiche correctement.
  • Lors du clic est ce que un carre rouge apparait en haut à droite ?
    • Oui, il y a bien un rafraichissement ajax.
  • Pour les clics suivants ?
    • Aussi.
  • Est ce qu'il y a des erreurs JavaScript ?
    • Non aucune.
  • Est ce que le gabarit de la Skin de la Portlet contient bien les outter css (dans la source il doit y avoir class="ID_c_1234 ... Ajax-Refresh-Div"
    • Oui il y a bien la classe CSS du ajax refresh

Olivier Jaquemet - on 1/21/09 at 5:42 PM

Nous avons pu reproduire le problème de notre coté, il est assez complexe...

Le problème est le suivant :

1. Causes
Si dans une requête normale une des 2 conditions suivantes est rencontrée :

  • une publication est affichée en fulldisplay
  • une publication est incluse via jalios:include

Alors l'attribut PortalManager.PORTAL_PUBLICATION n'est pas restoré à la valeur précédente. C'est le comportement normal. mais...

2. Conséquences
Après cela, si une requête Ajax est effectuée pour afficher une portlet, qui utilise les gabarits de resultDisplay, alors le dernier attribut PortalManager.PORTAL_PUBLICATION de la requête initial vient interférer dans l'affichage.

3. Explication
doInitPage.jsp repositionne l'attribut PortalManager.PORTAL_PUBLICATION chaque fois qu'il est appelé au lieu de le repositionner une seul fois lors du tout premier appel (check avec variable initDone).

4. Contournement
Le contournement que tu as trouvé dans ta première réponse permet d'éviter la cause du problème dans la requête initiale, à savoir, tu rétablir l'attribut PORTAL_PUBLICATION tel qu'il était avant le jalios:include (en l'occurrence null). De cette façon il ne vient pas surcharger celui de la requete ajax.

Cependant ce contournement ne corrige pas l'autre cause possible du problème suite à un affichage en full display...

5. Correctif
Nous sommes en train de le réaliser, il sera disponible dans la 6.0.1

Nicolas Plessis - on 1/21/09 at 5:46 PM

Et bien je suis ravi que mon mal de crâne d'hier ait servi à trouver un bug complexe.

Bonne fin de journée, je vais laisser ma portlet en l'état en attendant la 6.0.1.

Jean-Phillipe Encausse - on 1/21/09 at 6:41 PM

Je rajoute une précision qu'il faut qu'on intègre à la formation développeur d'ailleurs.

D'un manière générale quand vous faites des request.setAttributes() il est important de faire avant et après des ServletUtil.backupAttribute() et des ServletUtil.restoreAttribute()

  • Pour ne pas écraser les variables existante
  • Sauf si cela a un sens

Le tag <jalios:include> ne fait pas ce travail car cela peut effectivement avoir un sens.

Il faut que je vérifie, mais typiquement si vous utilisez le tag <jalios:include> sur une publication, l'attribut PORTAL_PUBLICATION est positionné indiquant qu'une publication est affichée dans la page. La mécanique des statistiques va loguer que cette publication est en cours de visualisation. C'est la raison pour laquelle:

  • La PortletSelection laisse cet attribut
  • les PortletQF l'enlève

Je ne sais pas si il y aurait une possibilité pour le tag <jalios:include> d'être plus intelligent.

Login   Home   fr en
JALIOS SA - SIREN 440 126 035