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

Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • La mise en forme a été modifiée.
Commentaire: Migrated to Confluence 5.3

 

Objectifs

 

Section
Colonne
width60%

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".

Colonne
width40%
canadian.mp4

Multimedia
namecanadian.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"

    Bloc de code
    languagehtml/xml
    titleuportal-war/src/main/resources/properties/contexts/requestParameterProcessingContext.xml
    collapsetrue
    <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

    Bloc de code
    titleportal-war/src/main/resources/layout/structure/columns/columns.xsl
    collapsetrue
    @@ -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>



    Bloc de code
    titleuportal-war/src/main/resources/layout/theme/universality/navigation.xsl
    collapsetrue
    @@ -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>
    
    



    Bloc de code
    titleuportal-war/src/main/resources/layout/theme/universality/universality.xsl
    collapsetrue
    @@ -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

    Bloc de code
    ant data-import -Dfile=...


    Descripteur de structure :

    Bloc de code
    titleuportal-war/src/main/data/required_entities/stylesheet-descriptor/DLMTabsColumns.stylesheet-descriptor.xml
    collapsetrue
    <!-- 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 :

    Bloc de code
    titleuportal-war/src/main/data/required_entities/stylesheet-descriptor/DLMXHTML.stylesheet-descriptor.xml
    collapsetrue
    <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

    Bloc de code
    titleuportal-war/src/main/webapp/media/skins/universality/common/scss/_navigation.scss
    collapsetrue
            /* 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.

    Bloc de code
    titleExemple d'ajout de l'attribut
    collapsetrue
            <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>