committing revision 8270. Merged from trunk.

This commit is contained in:
anupsawant 2011-06-21 20:27:19 +00:00
commit a78ae5acf7
25 changed files with 298 additions and 164 deletions

View file

@ -151,17 +151,12 @@ public class SparqlQueryServlet extends BaseEditController {
String queryParam = vreq.getParameter("query"); String queryParam = vreq.getParameter("query");
boolean graphPresent = false; boolean graphPresent = false;
StringTokenizer tokenizer = new StringTokenizer(queryParam, " "); String[] tokens = queryParam.split("\\s");
while(tokenizer.hasMoreTokens()){ for(int i = 0; i < tokens.length; i++){
if("graph".equalsIgnoreCase(tokenizer.nextToken())){ if("graph".equalsIgnoreCase(tokens[i])){
graphPresent = true; return vreq.getDataset();
break;
} }
} }
Dataset dataset = vreq.getDataset();
if (dataset != null && graphPresent) {
return dataset;
}
DataSource dataSource = DatasetFactory.create(); DataSource dataSource = DatasetFactory.create();
dataSource.setDefaultModel(vreq.getJenaOntModel()); dataSource.setDefaultModel(vreq.getJenaOntModel());

View file

@ -70,6 +70,10 @@ public class VitroRequest extends HttpServletRequestWrapper {
setAttribute("dataset", dataset); setAttribute("dataset", dataset);
} }
public void setJenaOntModel(OntModel ontModel) {
setAttribute("jenaOntModel", ontModel);
}
/** gets assertions + inferences WebappDaoFactory with no filtering **/ /** gets assertions + inferences WebappDaoFactory with no filtering **/
public WebappDaoFactory getFullWebappDaoFactory() { public WebappDaoFactory getFullWebappDaoFactory() {
Object webappDaoFactoryAttr = _req.getAttribute("fullWebappDaoFactory"); Object webappDaoFactoryAttr = _req.getAttribute("fullWebappDaoFactory");
@ -106,6 +110,10 @@ public class VitroRequest extends HttpServletRequestWrapper {
} }
public OntModel getJenaOntModel() { public OntModel getJenaOntModel() {
Object ontModel = getAttribute("jenaOntModel");
if (ontModel instanceof OntModel) {
return (OntModel) ontModel;
}
OntModel jenaOntModel = (OntModel)_req.getSession().getAttribute( JenaBaseDao.JENA_ONT_MODEL_ATTRIBUTE_NAME ); OntModel jenaOntModel = (OntModel)_req.getSession().getAttribute( JenaBaseDao.JENA_ONT_MODEL_ATTRIBUTE_NAME );
if ( jenaOntModel == null ) { if ( jenaOntModel == null ) {
jenaOntModel = (OntModel)_req.getSession().getServletContext().getAttribute( JenaBaseDao.JENA_ONT_MODEL_ATTRIBUTE_NAME ); jenaOntModel = (OntModel)_req.getSession().getServletContext().getAttribute( JenaBaseDao.JENA_ONT_MODEL_ATTRIBUTE_NAME );

View file

@ -78,6 +78,7 @@ public class IndividualController extends FreemarkerHttpServlet {
private static final String INCLUDE_ALL = "all"; private static final String INCLUDE_ALL = "all";
private static final Map<String, String> namespaces = new HashMap<String, String>() {{ private static final Map<String, String> namespaces = new HashMap<String, String>() {{
put("display", VitroVocabulary.DISPLAY);
put("vitro", VitroVocabulary.vitroURI); put("vitro", VitroVocabulary.vitroURI);
put("vitroPublic", VitroVocabulary.VITRO_PUBLIC); put("vitroPublic", VitroVocabulary.VITRO_PUBLIC);
}}; }};
@ -334,13 +335,7 @@ public class IndividualController extends FreemarkerHttpServlet {
private ResponseValues doRdf(VitroRequest vreq, Individual individual, private ResponseValues doRdf(VitroRequest vreq, Individual individual,
ContentType rdfFormat) throws IOException, ServletException { ContentType rdfFormat) throws IOException, ServletException {
OntModel ontModel = null; OntModel ontModel = vreq.getJenaOntModel();
HttpSession session = vreq.getSession(false);
if( session != null )
ontModel = (OntModel)session.getAttribute("jenaOntModel");
if( ontModel == null)
ontModel = (OntModel)getServletContext().getAttribute("jenaOntModel");
String[] includes = vreq.getParameterValues("include"); String[] includes = vreq.getParameterValues("include");
Model newModel = getRDF(individual,ontModel,ModelFactory.createDefaultModel(),0,includes); Model newModel = getRDF(individual,ontModel,ModelFactory.createDefaultModel(),0,includes);

View file

@ -10,6 +10,7 @@ import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime; import org.joda.time.DateTime;
@ -26,18 +27,14 @@ import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.AnonId; import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
@ -105,11 +102,65 @@ public class IndividualDaoSDB extends IndividualDaoJena {
ents.addAll(getIndividualsByVClass(vc)); ents.addAll(getIndividualsByVClass(vc));
} }
} else { } else {
List<Individual> individualList;
// Check if there is a graph filter.
// If so, we will use it in a slightly strange way. Unfortunately,
// performance is quite bad if we add several graph variables in
// order to account for the fact that an individual's type
// declaration may be in a different graph from its label or
// moniker. Thus, we will run two queries: one with a single
// graph variable to get the list of URIs, and a second against
// the union graph to get individuals with their labels and
// monikers. We will then toss out any individual in the second
// list that is not also in the first list.
// Annoying, yes, but better than the alternative.
// Note that both queries need to sort identically or
// the results may be very strange.
String[] graphVars = {"?g"};
String filterStr = WebappDaoFactorySDB.getFilterBlock(
graphVars, datasetMode);
if (!StringUtils.isEmpty(filterStr)) {
List<Individual> graphFilteredIndividualList =
getGraphFilteredIndividualList(theClass, filterStr);
List<Individual> unfilteredIndividualList = getIndividualList(
theClass);
Iterator<Individual> unfilteredIt = unfilteredIndividualList
.iterator();
for (Individual filt : graphFilteredIndividualList) {
Individual unfilt = unfilteredIt.next();
while (!unfilt.getURI().equals(filt.getURI())) {
unfilt = unfilteredIt.next();
}
ents.add(unfilt);
}
} else {
ents = getIndividualList(theClass);
}
}
java.util.Collections.sort(ents);
if (quantity > 0 && offset > 0) {
List<Individual> sublist = new ArrayList<Individual>();
for (int i = offset - 1; i < ((offset - 1) + quantity); i++) {
sublist.add(ents.get(i));
}
return sublist;
}
return ents;
}
private List<Individual> getIndividualList(Resource theClass) {
List<Individual> ents = new ArrayList<Individual>();
DatasetWrapper w = getDatasetWrapper(); DatasetWrapper w = getDatasetWrapper();
Dataset dataset = w.getDataset(); Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ); dataset.getLock().enterCriticalSection(Lock.READ);
try { try {
String[] graphVars = {"?g", "?h", "?i"};
String query = String query =
"SELECT DISTINCT ?ind ?label ?moniker " + "SELECT DISTINCT ?ind ?label ?moniker " +
"WHERE " + "WHERE " +
@ -166,20 +217,40 @@ public class IndividualDaoSDB extends IndividualDaoJena {
dataset.getLock().leaveCriticalSection(); dataset.getLock().leaveCriticalSection();
w.close(); w.close();
} }
}
java.util.Collections.sort(ents);
if (quantity > 0 && offset > 0) {
List<Individual> sublist = new ArrayList<Individual>();
for (int i = offset - 1; i < ((offset - 1) + quantity); i++) {
sublist.add(ents.get(i));
}
return sublist;
}
return ents; return ents;
}
private List<Individual> getGraphFilteredIndividualList(Resource theClass,
String filterStr) {
List<Individual> filteredIndividualList = new ArrayList<Individual>();
DatasetWrapper w = getDatasetWrapper();
Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ);
try {
String query =
"SELECT DISTINCT ?ind ?label ?moniker " +
"WHERE " +
"{ GRAPH ?g { \n" +
"{ ?ind a <" + theClass.getURI() + "> } \n" +
" } \n" + filterStr +
"} ORDER BY ?ind";
ResultSet rs =QueryExecutionFactory.create(
QueryFactory.create(query), dataset)
.execSelect();
while (rs.hasNext()) {
QuerySolution sol = rs.nextSolution();
Resource currRes = sol.getResource("ind");
if (currRes.isAnon()) {
continue;
}
filteredIndividualList.add(
makeIndividual(currRes.getURI(), null, null));
}
} finally {
dataset.getLock().leaveCriticalSection();
w.close();
}
return filteredIndividualList;
} }
private Individual makeIndividual(String uri, String label, String moniker) { private Individual makeIndividual(String uri, String label, String moniker) {

View file

@ -933,21 +933,18 @@ public class IndividualSDB extends IndividualImpl implements Individual {
if (ind.getModel().contains((Resource) null, RDF.type, (RDFNode) null)){ if (ind.getModel().contains((Resource) null, RDF.type, (RDFNode) null)){
tempModel = ind.getModel(); tempModel = ind.getModel();
} else { } else {
String[] graphVars = { "?g" };
String getTypes = String getTypes =
"CONSTRUCT{ <" + this.individualURI + "> <" + RDF.type + "CONSTRUCT{ <" + this.individualURI + "> <" + RDF.type +
"> ?types }\n" + "> ?types }\n" +
"WHERE{ GRAPH " + "WHERE{ GRAPH ?g"
((direct) + " { <" + this.individualURI +"> <" +RDF.type+ "> ?types } \n"
? "<http://vitro.mannlib.cornell.edu/default/vitro-kb-2>" + WebappDaoFactorySDB.getFilterBlock(
: "?g") graphVars, (direct
+ " { <" + this.individualURI +"> <" +RDF.type+ "> ?types } \n" ; ? WebappDaoFactorySDB.SDBDatasetMode
.ASSERTIONS_ONLY
if (!direct) { : datasetMode))
String[] graphVars = { "?g" }; + "} \n";
getTypes += WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode);
}
getTypes += "} \n";
DatasetWrapper w = getDatasetWrapper(); DatasetWrapper w = getDatasetWrapper();
Dataset dataset = w.getDataset(); Dataset dataset = w.getDataset();
dataset.getLock().enterCriticalSection(Lock.READ); dataset.getLock().enterCriticalSection(Lock.READ);

View file

@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
public class WebappDaoFactorySDB extends WebappDaoFactoryJena { public class WebappDaoFactorySDB extends WebappDaoFactoryJena {
public static final String UNION_GRAPH = "urn:x-arq:UnionGraph";
private SDBDatasetMode datasetMode = SDBDatasetMode.ASSERTIONS_AND_INFERENCES; private SDBDatasetMode datasetMode = SDBDatasetMode.ASSERTIONS_AND_INFERENCES;
/** /**

View file

@ -21,7 +21,9 @@ import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.sdb.SDBFactory; import com.hp.hpl.jena.sdb.SDBFactory;
import com.hp.hpl.jena.sdb.Store; import com.hp.hpl.jena.sdb.Store;
import com.hp.hpl.jena.sdb.StoreDesc; import com.hp.hpl.jena.sdb.StoreDesc;
@ -106,6 +108,9 @@ public class WebappDaoFactorySDBPrep implements Filter {
vreq.setWebappDaoFactory(wadf); vreq.setWebappDaoFactory(wadf);
vreq.setFullWebappDaoFactory(wadf); vreq.setFullWebappDaoFactory(wadf);
vreq.setDataset(dataset); vreq.setDataset(dataset);
vreq.setJenaOntModel(ModelFactory.createOntologyModel(
OntModelSpec.OWL_MEM, dataset.getNamedModel(
WebappDaoFactorySDB.UNION_GRAPH)));
} }
} catch (Throwable t) { } catch (Throwable t) {
log.error("Unable to filter request to set up SDB connection", t); log.error("Unable to filter request to set up SDB connection", t);

View file

@ -114,3 +114,92 @@
display: block; display: block;
padding-left: 15px; padding-left: 15px;
} }
/* -------------------------------------------------> */
/* DROP DOWN USER MENU ----------------------------> */
/* -------------------------------------------------> */
/* LEVEL ONE */
ul.dropdown {
position: relative;
}
ul.dropdown li {
float: left;
zoom: 1;
padding: 0 !important;
}
ul.dropdown li a {
display: block;
font-size: 1.4em;
}
ul.dropdown li#user-menu {
background: url(../images/arrowDownOverAccount.gif) right 9px no-repeat;
min-width:110px;
}
ul.dropdown li#user-menu a {
margin-right: 28px;
margin-left:10px;
}
ul.dropdown li#user-menu.hover,
ul.dropdown li#user-menu:hover {
color: #000 !important;
position: relative;
background: #fff url(../images/arrowDownAccount.gif) right 9px no-repeat;
border-bottom: 1px solid #cdcfcf;
}
ul.dropdown li.hover a,
ul.dropdown li:hover a {
color: #000 !important;
margin-left:10px;
}
/* LEVEL TWO */
ul.dropdown ul.sub_menu {
background-color: #fff;
font-size: 1.4em;
visibility: hidden;
position: absolute;
top: 100%;
right: 0;
z-index: 999;
color: #000;
}
ul.dropdown ul.sub_menu li {
float: none;
clear: both;
padding-left: 14px !important;
width: 96px;
border-right: none !important;
border-bottom: 1px solid #cdcfcf;
background: #fff url(../images/arrowMenuAccount.gif) 7px 8px no-repeat;
}
ul.dropdown ul.sub_menu li:last-child {
width: 96px;
}
/* IE 6 & 7 Needs Inline Block */
/* ADD IN IE6.css and IE7.css*/
ul.dropdown ul.sub_menu li a {
width: 90%;
display: inline-block;
color: #000 !important;
background-color: #fff;
padding: 0;
padding-left: 0px;
height: 24px;
}
ul.dropdown ul.sub_menu li.inactive {
color: #aab0ae !important;
font-size: 1em !important;
padding-left: 22px !important;
width: 88px;
}
ul.dropdown ul.sub_menu li a:hover,
ul.dropdown ul.sub_menu li a.hover {
color: #999 !important;
}
/* LEVEL THREE */
ul.dropdown ul ul {
left: 100%; top: 0;
}
ul.dropdown li:hover > ul {
visibility: visible;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 589 B

After

Width:  |  Height:  |  Size: 604 B

View file

@ -65,7 +65,7 @@
<label for="last-name">Last name<span class="requiredHint"> *</span></label> <label for="last-name">Last name<span class="requiredHint"> *</span></label>
<input type="text" name="lastName" value="${lastName}" id="last-name" role="input" /> <input type="text" name="lastName" value="${lastName}" id="last-name" role="input" />
<label for="external-auth-id">External authorization ID (optional)</label> <label for="external-auth-id">External authorization ID</label>
<input type="text" name="externalAuthId" value="${externalAuthId}" id="external-auth-id" role="input "/> <input type="text" name="externalAuthId" value="${externalAuthId}" id="external-auth-id" role="input "/>
<#if roles?has_content> <#if roles?has_content>

View file

@ -1,25 +1,29 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> <#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Default VIVO individual profile page template (extends individual.ftl in vitro) --> <#-- Menu management page (uses individual display mechanism) -->
<#include "individual-setup.ftl"> <#include "individual-setup.ftl">
<#assign individualProductExtension>
<#-- Include for any class specific template additions -->
${classSpecificExtension!}
<#include "individual-overview.ftl">
</section> <!-- #individual-info -->
</section> <!-- #individual-intro -->
</#assign>
<#assign nameForOtherGroup = "other"> <#-- used by both individual-propertyGroupMenu.ftl and individual-properties.ftl -->
<h3>Menu management</h3> <h3>Menu management</h3>
<#-- Menu Ontology properties --> <#assign hasElement = propertyGroups.pullProperty("${namespaces.display}hasElement")>
<#include "individual-menu-properties.ftl">
<#-- List the menu items -->
<#list hasElement.statements as statement>
Position | <#include "${hasElement.template}"> | <@p.editingLinks "hasElement" statement editable /> <br />
</#list>
<br /> <#-- remove this once styles are applied -->
<#-- Link to add a new menu item -->
<#if editable>
<#assign addUrl = hasElement.addUrl>
<#if addUrl?has_content>
<a class="add-hasElement green button" href="${addUrl}" title="Add new menu item">Add menu item</a>
</#if>
</#if>
<#-- Remove unneeded scripts and stylesheets -->
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/individual/individual.css" />', ${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/individual/individual.css" />',
'<link rel="stylesheet" href="${urls.base}/css/individual/individual-vivo.css" />')} '<link rel="stylesheet" href="${urls.base}/css/individual/individual-vivo.css" />')}

View file

@ -1,24 +0,0 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Template for menu management page -->
<#import "lib-properties.ftl" as p>
<#list propertyGroups.all as group>
<#assign groupName = group.getName(nameForOtherGroup)>
<#-- Display the group heading -->
<#if groupName?has_content>
<h2 id="${groupName}">${groupName?capitalize}</h2>
</#if>
<#-- List the menu items(properties) in the group -->
<#list group.properties as property>
<#if property.localName == "hasElement">
<#-- List menu Items -->
<@p.objectProperty property editable property.template />
<br /><#--remove break-->
<@p.addLink property editable />
</#if>
</#list>
</#list>

View file

@ -75,11 +75,7 @@ Assumes property is non-null. -->
<#macro objectPropertyList property editable statements=property.statements template=property.template> <#macro objectPropertyList property editable statements=property.statements template=property.template>
<#list statements as statement> <#list statements as statement>
<#if property.localName == "hasElement">
<@menuItem property statement editable><#include "${template}"></@menuItem>
<#else>
<@propertyListItem property statement editable><#include "${template}"></@propertyListItem> <@propertyListItem property statement editable><#include "${template}"></@propertyListItem>
</#if>
</#list> </#list>
</#macro> </#macro>
@ -96,16 +92,11 @@ name will be used as the label. -->
<#macro addLink property editable label="${property.name}" extraParams=""> <#macro addLink property editable label="${property.name}" extraParams="">
<#if editable> <#if editable>
<#--@dump var="property"/-->
<#local url = property.addUrl> <#local url = property.addUrl>
<#if url?has_content> <#if url?has_content>
<#if property.localName == "hasElement">
<@showAddMenuItemLink property.localName label addParamsToEditUrl(url, extraParams) />
<#else>
<@showAddLink property.localName label addParamsToEditUrl(url, extraParams) /> <@showAddLink property.localName label addParamsToEditUrl(url, extraParams) />
</#if> </#if>
</#if> </#if>
</#if>
</#macro> </#macro>
<#function addParamsToEditUrl url extraParams=""> <#function addParamsToEditUrl url extraParams="">
@ -249,12 +240,3 @@ name will be used as the label. -->
<@editingLinks "label" label editable /> <@editingLinks "label" label editable />
</#macro> </#macro>
<#-- Add menu item button -->
<#macro showAddMenuItemLink propertyLocalName label url>
<a class="add-${propertyLocalName} green button" href="${url}" title="Add new ${label?lower_case} entry">Add menu item</a>
</#macro>
<#-- List menu items -->
<#macro menuItem property statement editable >
Position | <#nested> | <@editingLinks "${property.localName}" statement editable/> <br />
</#macro>

View file

@ -422,6 +422,7 @@ ul#header-nav li.last {
border-right: none; border-right: none;
} }
ul#header-nav li:last-child { ul#header-nav li:last-child {
padding-left: 1px;
padding-right: 0; padding-right: 0;
border-right: none; border-right: none;
} }
@ -437,6 +438,9 @@ ul#header-nav a:active {
text-decoration: none; text-decoration: none;
color: #999; color: #999;
} }
ul#header-nav a.log-out {
padding-left: 10px;
}
/* SEARCH ------> */ /* SEARCH ------> */
#search { #search {
position: absolute; position: absolute;
@ -1319,7 +1323,7 @@ p.view-all-coauthors {
} }
section.property-group h2 { section.property-group h2 {
font-size: 1.25em; font-size: 1.25em;
color: #47B6D0; color: #006279;
font-weight: normal; font-weight: normal;
} }
article.property { article.property {
@ -1328,7 +1332,7 @@ article.property {
article.property h3 { article.property h3 {
background: #fafaf9; background: #fafaf9;
font-size: 1.063em; font-size: 1.063em;
color: #8aa149; color: #a8833e;
} }
article.property ul.property-list li.subclass h3 { article.property ul.property-list li.subclass h3 {
font-size: 1.063em; font-size: 1.063em;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

View file

@ -25,6 +25,7 @@
<#if urls.contact??> <#if urls.contact??>
<li role="listitem"><a href="${urls.contact}">Contact Us</a></li> <li role="listitem"><a href="${urls.contact}">Contact Us</a></li>
</#if> </#if>
<li role="listitem"><a href="http://www.vivoweb.org/support" target="blank">Support</a></li>
</ul> </ul>
</nav> </nav>
</footer> </footer>

View file

@ -9,23 +9,29 @@
<nav role="navigation"> <nav role="navigation">
<ul id="header-nav" role="list"> <ul id="header-nav" role="list">
<li role="listitem"><a href="${urls.index}">Index</a></li>
<#if user.loggedIn> <#if user.loggedIn>
<li role="listitem"><img class="middle" src="${urls.images}/userIcon.png" alt="user icon" />${user.loginName}</li>
<li role="listitem"><a href="${urls.logout}">Log out</a></li>
<#if user.hasSiteAdminAccess> <#if user.hasSiteAdminAccess>
<li role="listitem"><a href="${urls.siteAdmin}">Site Admin</a></li> <li role="listitem"><a href="${urls.siteAdmin}">Site Admin</a></li>
</#if> </#if>
<#else> <li>
<li role="listitem"><a title="log in to manage this site" href="${urls.login}">Log in</a></li> <ul class="dropdown">
</#if> <li id="user-menu"><a href="#">${user.loginName}</a>
<#-- List of links that appear in submenus, like the header and footer. --> <ul class="sub_menu">
<li role="listitem"><a href="${urls.about}">About</a></li> <li role="listitem"><a href="${urls.myAccount}">My account</a></li>
<#if urls.contact??> <li role="listitem"><a href="${urls.logout}">Log out</a></li>
<li role="listitem"><a href="${urls.contact}">Contact Us</a></li>
</#if>
<li role="listitem"><a href="http://www.vivoweb.org/support" target="blank">Support</a></li>
<li role="listitem"><a href="${urls.index}">Index</a></li>
</ul> </ul>
</li>
</ul>
</li>
${scripts.add('<script type="text/javascript" src="${urls.base}/js/userMenu/userMenuUtils.js"></script>')}
<#else>
<li role="listitem"><a class="log-out" title="log in to manage this site" href="${urls.login}">Log in</a></li>
</#if>
</ul>
</nav> </nav>
<section id="search" role="region"> <section id="search" role="region">