Avatar billede dsj Nybegynder
12. november 2005 - 23:10 Der er 9 kommentarer og
2 løsninger

Opbygning af menu med Struts

Jeg prøver at opbygge en menu i min Struts-applikation, men savner nogle best practises. Jeg har forsøgt på den helt simple måde med en række <html:link>, men kan ikke helt finde ud af, hvordan jeg "disabler" linket til den aktive side. I PHP eller ASP.NET plejer jeg at oprette en page-attribut i session, hvori jeg gemmer navnet på den aktive side, og som menuen bruger til at finde ud af, hvilket link der er valgt.

Hvordan strukturerer og opbygger man "normalt" menuer i Struts? Jeg har kigget på <logic:notEmpty>, som jeg godt kan få til at kigge i session, men har ikke fundet ud af, hvordan jeg får sat værdien i session - og det må meget gerne ske i selve JSP-siden sammen med resten af menu-koden.

Bør det gøres på en anden måde? Ved valg af enkle menu-punkter, skal flere nye underpunkter kommer til syne, men ellers er der ikke tale om en funktionelt avanceret menu.
Avatar billede dsj Nybegynder
12. november 2005 - 23:17 #1
Enkelte menu-punkter skal dog skjules, så længe brugeren ikke er logget ind. Bruger-autentifikationen har jeg selv implementeret, som en LoginAction, der lægger et egenudviklet Profile-objekt i session, som menuen kan tjekke op mod med <logic:notEmpty>.
Avatar billede arne_v Ekspert
12. november 2005 - 23:23 #2
jeg formoder at du ikke vil bruge scriptlet kode (<% %>)

supplerer du Struts tags med JSTL tags ?  fordi JSTL har et set tag til dette formål !
Avatar billede dsj Nybegynder
12. november 2005 - 23:32 #3
Jeg vil nemlig ikke bruge scriplets, ellers havde det været piece of cake :-)

JSTL-tags har jeg ikke anvendt indtil videre, og har heller ikke tænkt at gøre det - har Struts virkelig ikke et tag til det?

Jeg har kigget lidt på Struts Menu-frameworket, men synes at det virker lidt som overkill til min forholdsvis simple menu. ved du hvordan folk normalt opbygger menuer i Struts?
Avatar billede arne_v Ekspert
12. november 2005 - 23:43 #4
Jeg er ikke den store ørn til Struts.

bean:define måske ?
Avatar billede dsj Nybegynder
12. november 2005 - 23:49 #5
<bean:define id="page" value="nyheder"/>

Har ingen effekt på - måske skriver jeg det forkert?

<logic:notEmpty name="page">
...
<logic:notEmpty>
Avatar billede arne_v Ekspert
13. november 2005 - 00:13 #6
page er vist et reserveret navn

følgende virker hos mig:

<%@ taglib uri="struts-logic" prefix="logic" %>
<%@ taglib uri="struts-bean" prefix="bean" %>
<bean:define id="mypage" value="nyheder"/>
<logic:notEmpty name="mypage">
Det virker.
</logic:notEmpty>
Avatar billede dsj Nybegynder
13. november 2005 - 01:09 #7
Ja, det gør det også hos mig nu. Fejlen var, at jeg havde skrevet scope="session" på begge statements, men på <bean:define...> skulle jeg egentlig have skrevet toScope="session".

Det næste er så, hvordan jeg får sat "mypage" til "forside", når der er trykket på forside-linket, og "nyheder", når brugeren har trykket på nyheds-linket. Jeg har prøvet at sætte bean:define ind i html:link, men så bliver bean:define altid afviklet, hvilket egentlig også siger sig selv:

<html:link action="news">Nyheder<br>
  <bean:define id="mypage" toScope="session" value="nyheder"/>
</html:link>
Avatar billede arne_v Ekspert
13. november 2005 - 10:44 #8
skal den ikke bare sættes på forsiden ?
Avatar billede dsj Nybegynder
13. november 2005 - 13:34 #9
Hmm jo, selvfølgelig skal den det.

Smid et svar :-)
Avatar billede arne_v Ekspert
13. november 2005 - 17:53 #10
kommer her
Avatar billede dsj Nybegynder
13. november 2005 - 19:01 #11
Nu fandt jeg en lidt bedre løsning baseret på Tiles (som jeg allerde anvender sammen med Struts): http://www.lifl.fr/~dumoulin/tiles/doc/tutorial.html - tilhørende kode og live-eksempler findes her: http://www.assortedinternet.com/tiles-documentation/tutorial/index.jsp

Løsningen er baseret på, at menuen er beskrevet som to lister i tiles-defs.xml, én til links og én til navne. Hvilket punkt der er valgt valideres mod title-attributten, menu-logikken er nødt til at blive placeret i template.jsp og ikke i en seperat menu.jsp, som beskrevet i eksemplet. Fordelen ved at dette er, at det netop er muligt at validere mod title-attributten. Placeres menu-logikken i en anden fil end templaten, er man nødt til at introducere en ny tiles-attribut, f.eks. "selected", som skal sættes i hver enkelt side-fil. Jeg kan bedre lide min egen løsning, hvor al hele menuen alt inkls. kan opbygges i tiles-def.xml og ikke er spredt ud over en masse filer. Følgende er definitionerne fra min egen tiles-def.xml:

<tiles-definitions>
  <definition name="index" path="/WEB-INF/template/template.jsp">
    <put name="title" type="string" value="Forside"/>
    <put name="header" value="/WEB-INF/web/header.jsp"/>
    <put name="body" value="/WEB-INF/web/introduction.jsp"/>
    <put name="right" value="/WEB-INF/web/sidebar.jsp"/>
    <putList name="items">
      <add value="Forside"/>
      <add value="Nyheder"/>
      <add value="Butik"/>
    </putList>
    <putList name="links">
      <add value="index.do"/>
      <add value="news.do"/>
      <add value="shop.do"/>
    </putList>
  </definition>
</tiles-definitions>

Da de to lister, items og links, skal itereres igennem på samme tid, er man nødt til at bruge lidt scriptlet, følgende er menu-logikken:

<%-- Push component attributes in page context --%>
<tiles:importAttribute />

<table>
  <%-- Prepare the links list to be iterated --%>
  <bean:define id="links" name="links" type="java.util.List" scope="page" />
  <% Iterator i = links.iterator(); %>
 
  <logic:iterate id="iterateItem" name="items" >
    <bean:define id="item" name="iterateItem" type="java.lang.String" scope="page" />
   
    <tr>
      <td width="10" valign="top" ></td>
      <td valign="top"  >
        <%-- check if selected --%>
        <% String link = (String)i.next(); %>
        <logic:notEqual name="selected" value="<%=item%>">
          <% // Compute link value
          if(link.startsWith("/") )
          link = request.getContextPath() + link;
          %>
          <font size="-1"><a href="<%=link%>"><%=item%></a></font>
        </logic:notEqual>
        <logic:equal name="selected" value="<%=item%>">
          <%=item%>
        </logic:equal>
      </td>
    </tr>
  </logic:iterate>
</table>

I forhold til eksemplet er String link = (String)i.next(); flyttet ud af logic:notEquals, da i.next() ellers ikke bliver kaldt for det ene punkt der er valgt (med forkerte links til følge).

Håber nogen kan få glæde af denne løsning :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester