Pages enfant
  • Navigation portlet pleine page (navigation "canadienne")

 

Objectifs

 

La mise en page par défaut d'esup-portail v4 est un affichage de type dashboard. Ceci peut poser problème :

  • lorsqu'un onglet comporte beaucoup de portlets
  • lorsque certaines portlets nécessitent un affichage pleine page, une seule colonne est alors créée avec le risque de faire perdre énormément en visibilité aux portlets en bas de page


Pour y remédier, l'idée est d'utiliser une navigation n'affichant, pour un onglet donné, qu'un service à la fois. Lorsqu'une portlet de l'onglet est visualisée, un sous-menu apparaît permettant d'accéder aux autres portlets de l'onglet.

Olivier Franco (INSA Lyon) a développé un package de modifications permettant de rendre paramétrable ce comportement au niveau des onglets. Le nom de code utilisé par la suite est "navigation canadienne".

canadian.mp4

Implémentation

  1. Télécharger les fichiers nécessaires : canadian.zip

  2. copier uportal-war/src/main/java/org/jasig/portal/url/processing/TargetChannelIDParameterProcessor.java

  3. Modifier uportal-war/src/main/resources/properties/contexts/requestParameterProcessingContext.xml

    référencer le bean "targetChannelIDRequestParameterProcessor" dans le "requestParameterProcessorInterceptor"

    uportal-war/src/main/resources/properties/contexts/requestParameterProcessingContext.xml
    <bean id="requestParameterProcessorInterceptor" ...>
        <property name="dynamicRequestParameterProcessors">
            <list value-type="org.jasig.portal.url.processing.IRequestParameterProcessor">
                <ref bean="..."/>
                <ref bean="..."/>
                <ref bean="..."/>
                <!-- targetChannelID -->
                <ref bean="targetChannelIDRequestParameterProcessor"/>
            </list>
        </property>
    </bean>


    Ce processeur permet l'injection de l'indentifiant du canal courant (celui dans lequel on agit) dans les feuilles de transformation :

    • de structure
    • de theme


  4. Modifier les feuilles xsl suivantes

    portal-war/src/main/resources/layout/structure/columns/columns.xsl
    @@ -29,4 +29,6 @@
     <xsl:param name="defaultTab">1</xsl:param>
     <xsl:param name="detached">false</xsl:param>
     <xsl:param name="userImpersonating">false</xsl:param>
    +<!-- ofranco -->
    +<xsl:param name="targetChannelID">none</xsl:param>
    @@ -74,5 +74,6 @@
             <activeTabGroup><xsl:value-of select="$activeTabGroup"></xsl:value-of></activeTabGroup>
             <tabsInTabGroup><xsl:value-of
     select="count(/layout/folder/folder[@tabGroup=$activeTabGroup and 
    @type='regular' and @hidden='false'])"/></tabsInTabGroup>
             <userImpersonation><xsl:value-of select="$userImpersonating"/></userImpersonation>
    +                <targetChannelID><xsl:value-of select="$targetChannelID"/></targetChannelID>
         </debug>    
     </xsl:template>
    @@ -199,6 +192,18 @@
                 <xsl:attribute name="activeTab">false</xsl:attribute>
               </xsl:otherwise>
             </xsl:choose>
    +        <xsl:if test="@canadianModeEmulation='true'">
    +                    <xsl:choose>
    +                        <!-- more than one column; disable canadianModeEmulation -->
    +                        <xsl:when test="count(child::folder) &gt; 1">
    +                            <xsl:attribute name="canadianModeEmulation"><xsl:value-of select="'false'"/></xsl:attribute>
    +                        </xsl:when>
    +                        <!-- no targetChannelID the take first channel -->
    +                        <xsl:when test="count(child::folder/channel[@ID=$targetChannelID]) &lt; 1">
    +                            <xsl:attribute name="targetChannelID"><xsl:value-of select="child::folder/channel[position()=1]/@ID"/></xsl:attribute>
    +                        </xsl:when>
    +                    </xsl:choose>
    +        </xsl:if>
             <xsl:for-each select="./descendant::channel">
               <tabChannel name="{@name}" title="{@title}" ID="{@ID}" fname="{@fname}" description="{@description}">
                 <xsl:choose>
    @@ -249,9 +254,18 @@
       </navigation>
     </xsl:template>
    
     <xsl:template match="folder[@hidden='false']">
    +    <!-- on ne prend que le tab courant -->
       <xsl:if test="$activeTabID = @ID">
         <xsl:if test="child::folder">
    +      <xsl:variable name="columnCount" select="count(child::folder)"/>
    +            <!-- si mode canadien et plus de une colonne; on annule le mode canadien -->
    +      <xsl:variable name="doCanadianModeEmulation">
    +          <xsl:choose>
    +              <xsl:when test="@canadianModeEmulation='true' and $columnCount &lt; 2"><xsl:value-of select="@canadianModeEmulation"/></xsl:when>
    +              <xsl:otherwise><xsl:value-of select="'false'"/></xsl:otherwise>
    +      </xsl:choose>
    +      </xsl:variable>
           <xsl:for-each select="folder">
             <column>
                 <xsl:attribute name="ID">
    @@ -298,7 +294,23 @@
                     <xsl:value-of select="@dlm:precedence"/>
                   </xsl:attribute>
                 </xsl:if>
    +            <xsl:choose>
    +                <xsl:when test="$doCanadianModeEmulation='true'">
    +                    <xsl:attribute name="canadianModeEmulation"><xsl:value-of select="$doCanadianModeEmulation"/></xsl:attribute>
    +                    <xsl:choose>
    +                        <xsl:when test="$targetChannelID != 'none' and child::channel[@ID=$targetChannelID]">
    +                            <xsl:apply-templates select="child::channel[@ID=$targetChannelID]"/>
    +                        </xsl:when>
    +                        <xsl:otherwise>
    +                            <!-- first one -->
    +                            <xsl:apply-templates select="child::channel[position()=1]"/>
    +                        </xsl:otherwise>
    +                    </xsl:choose>
    +                </xsl:when>
    +                <xsl:otherwise>
               <xsl:apply-templates/>
    +                </xsl:otherwise>                
    +            </xsl:choose>
             </column>
           </xsl:for-each>
         </xsl:if>



    uportal-war/src/main/resources/layout/theme/universality/navigation.xsl
    @@ -121,14 +121,28 @@
                  </xsl:apply-templates>
                 </ul>
    
    -            <xsl:if test="$USE_SUBNAVIGATION_ROW='true'">
    +               <xsl:choose>
    +                   <xsl:when test="$USE_SUBNAVIGATION_ROW='true'">
                   <div id="portalNavigationSubrow">
                     <xsl:call-template name="subnavigation">
                       <xsl:with-param name="CONTEXT" select="'subnav'"/>
                       <xsl:with-param name="TAB_POSITION" select="count(tab[@activeTab='true']/preceding-sibling::tab) + 1"/>
                     </xsl:call-template>
                   </div>
    -            </xsl:if>
    +                   </xsl:when>
    +                            <!-- if canadianModeEmulation for the activeTab and  more than one channel -->
    +                   <xsl:when test="count(tab[@activeTab='true' and @canadianModeEmulation='true']/tabChannel) &gt; 1">
    +                                <!-- ensure tab element selected before call to subnavigation -->
    +                       <xsl:for-each select="tab[@activeTab='true' and @canadianModeEmulation='true']">
    +                                    <div id="portalNavigationSubrow">
    +                                        <xsl:call-template name="subnavigation">
    +                                            <xsl:with-param name="CONTEXT" select="'subnav'"/>
    +                                            <xsl:with-param name="TAB_POSITION" select="count(tab[@activeTab='true']/preceding-sibling::tab) + 1"/>
    +                                        </xsl:call-template>
    +                                    </div>
    +                       </xsl:for-each>
    +                   </xsl:when>
    +               </xsl:choose>
               </div>
             </div>
    
    @@ -413,7 +419,8 @@
             <ul class="portal-subnav-list"> <!-- List of the subnavigation menu items. -->
                 <xsl:choose>
                   <xsl:when test="$CONTEXT='flyout'">
    -            
    +                <xsl:variable name="TAB_ID" select="@ID"/>
    +                <xsl:variable name="TAB_CANADIAN_MODE" select="@canadianModeEmulation"/>
                   <xsl:for-each select="tabChannel">
                     <xsl:if test="not(@hideFromDesktop='true')">
                     <xsl:variable
     name="SUBNAV_POSITION"> <!-- Determine the position of the 
    navigation option within the whole navigation list and add css hooks for
     the first and last positions. -->
    @@ -426,6 +433,33 @@
                     </xsl:variable>
                    
     <li id="portalSubnavLink_{@ID}" class="portal-subnav {$SUBNAV_POSITION} {@fname}"> <!-- Each subnavigation menu item.  
    The unique ID can be used in the CSS to give each menu item a unique 
    icon, color, or presentation. -->
                       <xsl:variable name="portletSubNavLink">
    +                      <xsl:choose>
    +                          <!-- if canadian tab the render normal link -->
    +                          <xsl:when test="$TAB_CANADIAN_MODE='true'">
    +                              <xsl:call-template name="portalUrl">
    +                                      <xsl:with-param name="url">
    +                                          <url:portal-url>
    +                                              <url:layoutId><xsl:value-of select="@ID"/></url:layoutId>
    +                                              <url:portlet-url state="NORMAL" copyCurrentRenderParameters="true"/>
    +                                          </url:portal-url>
    +                                      </xsl:with-param>
    +                                  </xsl:call-template>
    +                          </xsl:when>
    +                          <!-- if global parameter  -->
    +                          <xsl:when test="$subNavigationLinkAsAnchor='true'">
    +                              <xsl:variable name="subNavLinkTmp">
    +                                <xsl:call-template name="portalUrl">
    +                                    <xsl:with-param name="url">
    +                                        <url:portal-url>
    +                                            <url:layoutId><xsl:value-of select="$TAB_ID"/></url:layoutId>
    +                                        </url:portal-url>
    +                                    </xsl:with-param>
    +                                </xsl:call-template>
    +                            </xsl:variable>
    +                            <xsl:value-of select="concat($subNavLinkTmp,'#portlet_',@ID)"/>
    +                          </xsl:when>
    +                          <!-- render normal -->
    +                          <xsl:otherwise>
                         <xsl:call-template name="portalUrl">
                             <xsl:with-param name="url">
                                 <url:portal-url>
    @@ -434,12 +468,12 @@
                                 </url:portal-url>
                             </xsl:with-param>
                         </xsl:call-template>
    +                          </xsl:otherwise>
    +                    </xsl:choose>
                       </xsl:variable>
    -                  <div class="up-portlet-fname-subnav-wrapper {@fname}">
                        
     <a href="{$portletSubNavLink}" title="{@description}" 
    class="portal-subnav-link">  <!-- Navigation item link. -->
                             <span class="portal-subnav-label"><xsl:value-of select="@title"/></span>
                         </a>
    -                  </div>
                     </li>
                     </xsl:if>
                   </xsl:for-each>
    @@ -449,6 +483,8 @@
    
                   <xsl:for-each select="//navigation/tab[@activeTab='true']/tabChannel">
                     <xsl:if test="not(@hideFromDesktop='true')">
    +                <xsl:variable name="TAB_ID" select="parent::tab/@ID"/>
    +                                <xsl:variable name="TAB_CANADIAN_MODE" select="parent::tab/@canadianModeEmulation"/>
                     <xsl:variable
     name="SUBNAV_POSITION"> <!-- Determine the position of the 
    navigation option within the whole navigation list and add css hooks for
     the first and last positions. -->
                       <xsl:choose>
                         <xsl:when test="position()=1 and position()=last()">single</xsl:when>
    @@ -457,8 +493,53 @@
                         <xsl:otherwise></xsl:otherwise>
                       </xsl:choose>
                     </xsl:variable>
    -               
     <li id="uPfname_{@fname}" class="portal-subnav {$SUBNAV_POSITION}"> <!-- Each subnavigation menu item.  The 
    unique ID can be used in the CSS to give each menu item a unique icon, 
    color, or presentation. -->
    +                <xsl:variable name="SUBNAV_SELECTED">
    +                    <xsl:choose>
    +                        <xsl:when test="$TAB_CANADIAN_MODE='true' and (@ID=$targetChannelID or @ID=parent::tab/@targetChannelID)">active</xsl:when>
    +                        <xsl:otherwise></xsl:otherwise>
    +                    </xsl:choose>
    +                </xsl:variable>
    +               
     <li id="uPfname_{@fname}" class="portal-subnav {$SUBNAV_POSITION} {$SUBNAV_SELECTED}"> <!-- Each subnavigation menu item.  The 
    unique ID can be used in the CSS to give each menu item a unique icon, 
    color, or presentation. -->
                       <xsl:variable name="portletSubNavLink">
    +                      <xsl:choose>
    +                          <!-- if canadian tab the render normal link -->
    +                          <xsl:when test="$TAB_CANADIAN_MODE='true'">
    +                            <xsl:call-template name="portalUrl">
    +                                 <xsl:with-param name="url">
    +                                     <url:portal-url>
    +                                         <url:layoutId><xsl:value-of select="@ID"/></url:layoutId>
    +                                         <url:portlet-url state="NORMAL" copyCurrentRenderParameters="true"/>
    +                                     </url:portal-url>
    +                                 </xsl:with-param>
    +                             </xsl:call-template>
    +                          </xsl:when>
    +                        <!-- if global parameter -->
    +                        <xsl:when test="$subNavigationLinkAsAnchor='true'">
    +                            <xsl:variable name="subNavLinkTmp">
    +                                <xsl:call-template name="portalUrl">
    +                                    <xsl:with-param name="url">
    +                                        <url:portal-url>
    +                                            <url:layoutId><xsl:value-of select="$TAB_ID" /></url:layoutId>
    +                                        </url:portal-url>
    +                                    </xsl:with-param>
    +                                </xsl:call-template>
    +                            </xsl:variable>
    +                            <xsl:value-of select="concat($subNavLinkTmp,'#portlet_',@ID)" />
    +                        </xsl:when>
    +                        <!-- render normal -->
    +                        <xsl:otherwise>
    +                            <xsl:call-template name="portalUrl">
    +                                <xsl:with-param name="url">
    +                                    <url:portal-url>
    +                                        <url:layoutId><xsl:value-of select="@ID" /></url:layoutId>
    +                                        <url:portlet-url state="MAXIMIZED"
    +                                            copyCurrentRenderParameters="true" />
    +                                    </url:portal-url>
    +                                </xsl:with-param>
    +                            </xsl:call-template>
    +                        </xsl:otherwise>
    +                    </xsl:choose>
    +                          <!-- 
                         <xsl:call-template name="portalUrl">
                             <xsl:with-param name="url">
                                 <url:portal-url>
    @@ -467,6 +548,7 @@
                                 </url:portal-url>
                             </xsl:with-param>
                         </xsl:call-template>
    +                    -->
                       </xsl:variable>
                      
     <a href="{$portletSubNavLink}" title="{@description}" 
    class="portal-subnav-link">  <!-- Navigation item link. -->
                         <span class="portal-subnav-label"><xsl:value-of select="@title"/></span>
    
    



    uportal-war/src/main/resources/layout/theme/universality/universality.xsl
    @@ -131,6 +131,10 @@
       <xsl:param name="userImpersonating">false</xsl:param>
       <xsl:param name="skin">uportal3</xsl:param>
       <xsl:param name="CONTEXT_PATH">/NOT_SET</xsl:param>
    +  <!-- ofranco -->
    +  <xsl:param name="subNavigationLinkAsAnchor">false</xsl:param>
    +  <!-- ofranco -->
    +  <xsl:param name="targetChannelID">none</xsl:param>
       <xsl:variable name="SKIN" select="$skin"/>
       <xsl:variable name="MEDIA_PATH">media/skins/universality</xsl:variable>
       <xsl:variable name="ABSOLUTE_MEDIA_PATH" select="concat($CONTEXT_PATH,'/',$MEDIA_PATH)"/>
    @@ -922,6 +904,32 @@
                           <ul>
                               <xsl:for-each select="tabChannel">
                                   <xsl:variable name="portletLinkUrl">
    +                                  <xsl:choose>
    +                                      <xsl:when test="parent::tab[@canadianModeEmulation='true']">
    +                                           <!-- on canadianModeEmulation show normal portlet -->
    +                                           <xsl:call-template name="portalUrl">
    +                                               <xsl:with-param name="url">
    +                                                   <url:portal-url>
    +                                                       <url:layoutId><xsl:value-of select="@ID"/></url:layoutId>
    +                                                       <url:portlet-url state="NORMAL"/>
    +                                                   </url:portal-url>
    +                                               </xsl:with-param>
    +                                           </xsl:call-template>
    +                                       </xsl:when>
    +                                       <xsl:when test="$subNavigationLinkAsAnchor='true'">
    +                                           <!-- otherwise show full layout -->
    +                                           <xsl:variable name="tmpPortletLinkUrl">
    +                                               <xsl:call-template name="portalUrl">
    +                                                   <xsl:with-param name="url">
    +                                                       <url:portal-url>
    +                                                           <url:layoutId><xsl:value-of select="parent::tab/@ID"/></url:layoutId>
    +                                                       </url:portal-url>
    +                                                   </xsl:with-param>
    +                                               </xsl:call-template>
    +                                           </xsl:variable>
    +                                           <xsl:value-of select="concat($tmpPortletLinkUrl,'#portlet_',@ID)"/>
    +                                       </xsl:when>
    +                                      <xsl:otherwise> <!-- normal behavior -->
                                   <xsl:call-template name="portalUrl">
                                     <xsl:with-param name="url">
                                       <url:portal-url>
    @@ -930,6 +938,8 @@
                                       </url:portal-url>
                                     </xsl:with-param>
                                   </xsl:call-template>
    +                                      </xsl:otherwise>
    +                                  </xsl:choose>
                                 </xsl:variable>
                                 <li><a href="{$portletLinkUrl}"><xsl:value-of select="@name" /></a></li>
                             </xsl:for-each>



  5. modifier les descripteurs de theme et de structure et les réimporter

    ant data-import -Dfile=...


    Descripteur de structure :

    uportal-war/src/main/data/required_entities/stylesheet-descriptor/DLMTabsColumns.stylesheet-descriptor.xml
    <!-- injection du targetChannelID -->
    <stylesheet-parameter>
        <name>targetChannelID</name>
        <default-value>none</default-value>
        <scope>REQUEST</scope>
        <description>current target channel ID</description>
    </stylesheet-parameter>
    <!--  
        canadianModeEmulation / persistant par fragment-layout; 
        bien penser à la mettre à "false" dans le descripteur de structure
        car systématiquement injecté dans les attributs. 
        On surchargera l'activation du mode canadian dans les fragment-layouts
     -->
    <layout-attribute>
        <name>canadianModeEmulation</name>
        <default-value>false</default-value>
        <scope>PERSISTENT</scope>
        <description>enable/disable canadian mode per fragment layout</description>
        <targetElement>folder</targetElement>
    </layout-attribute>


    Descripteur de thèmes :

    uportal-war/src/main/data/required_entities/stylesheet-descriptor/DLMXHTML.stylesheet-descriptor.xml
    <stylesheet-parameter>
        <name>subNavigationLinkAsAnchor</name>
        <default-value>false</default-value>
        <scope>PERSISTENT</scope>
        <description>render subnavigation link as Anchor</description>
    </stylesheet-parameter>
    
    <!-- injection du targetChannelID -->
    <stylesheet-parameter>
        <name>targetChannelID</name>
        <default-value>none</default-value>
        <scope>REQUEST</scope>
        <description>inform theme of the current targeted channel</description>
    </stylesheet-parameter>



  6. Ajout de style pour prise en compte de la navigation

    uportal-war/src/main/webapp/media/skins/universality/common/scss/_navigation.scss
            /* canadian mode subnavigation */
    .up #portalNavigation #portalNavigationSubrow {
                .portal-subnav-list { 
                    margin: 0 2em; 
                  .active {
                        background: none!important;
                    }
                }
                a.portal-subnav-link { 
                    text-decoration: none; 
                    .portal-subnav-label {
                        color: white;
                        font-weight: bold;
                    }
                    .portal-subnav-label:hover {
                        border-bottom: 2px solid $navTabActiveHoverLink;
                    }
                }
                .active .portal-subnav-link .portal-subnav-label { 
                    border-bottom: 2px solid $navTabActiveHoverLink; 
                }
            }



  7. Appliquer le mode "canadien" sur un onglet en ajoutant l'attribut "canadianModeEmulation"

    L'attribut s'applique sur le folder correspondant à l'onglet et non à celui de la colonne. De plus, l'onglet ne doit contenir qu'une seule colonne sinon l'attribut ne sera pas pris en compte.

    Exemple d'ajout de l'attribut
            <folder ID="s5" dlm:addChildAllowed="false" dlm:deleteAllowed="false"    dlm:editAllowed="false" dlm:moveAllowed="false" hidden="false"
                immutable="false" name="Test canadien" type="regular" unremovable="true">
    
    
                <!-- activation du mode canadien : au niveau du folder "onglet" -->
                <structure-attribute>
                    <name>canadianModeEmulation</name>
                    <value>true</value>
                </structure-attribute>
    
    
                <!-- la colonne : seulement une; si plusieurs; annule le mode canadien -->
                <folder ID="s6" dlm:addChildAllowed="false" dlm:deleteAllowed="false"    dlm:editAllowed="false" dlm:moveAllowed="false" hidden="false"
                    immutable="false" name="Column" type="regular" unremovable="false">
                    <structure-attribute>
                        <name>width</name>
                        <value>100%</value>
                    </structure-attribute>
                    <!-- canal 1 -->
                    <channel fname="channel1-portlet" unremovable="false" hidden="false"
                        immutable="false" ID="n13" dlm:moveAllowed="false"
    dlm:deleteAllowed="false" />
                    <!-- canal 2 -->
                    <channel fname="channel2-portlet" unremovable="false" hidden="false"
                        immutable="false" ID="n14" dlm:moveAllowed="false"
    dlm:deleteAllowed="false" />
                    <!-- canal 3 -->
                    <channel fname="channel3-portlet" unremovable="false" hidden="false"
                        immutable="false" ID="n15" dlm:moveAllowed="false"
    dlm:deleteAllowed="false" />
                    <!-- etc -->
                </folder>
            </folder>

     

     

     

     

 

 

  • Aucune étiquette