Expanding on the GS3 Customisation tutorials

This wiki explains how to introduce support for other Greenstone 3 features into the custom perrin interface created by following the Greenstone 3 tutorial series on Designing a new interface.

Displaying collection groups

If you have edited web/sites/<sitename>/groupConfig.xml to set up collection groups, then you can add support for your collection groups into the perrin Greenstone3 interface by editing web/interfaces/perrin/transform/pages/home.xsl as follows:

1. Change:

<div id="hpage_cats">
  <xsl:call-template name="collectionsList"/>
</div>

to:

<div id="hpage_cats">
  <!--<xsl:call-template name="collectionsList"/>-->
  <xsl:call-template name="collectionsOrGroupsList"/>
</div>

2. Before the terminating </xsl:stylesheet> add:

<xsl:template name="collectionsOrGroupsList">
  <xsl:for-each select="./collectionList/collection|groupList/group">
    <xsl:choose>
      <xsl:when test="position() mod 2 = 1">
        <div class="fl_left">
      	  <xsl:call-template name="collOrGroupDescription"/>
        </div>
      </xsl:when>
      <xsl:otherwise>
        <div class="fl_right">
	  <xsl:call-template name="collOrGroupDescription"/>
        </div>
        <br class="clear" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>


<xsl:template name="collOrGroupDescription">
	<xsl:if test="name() = 'group'">
	  <xsl:call-template name="customGroupDescription"/><!--<gslib:groupLinkWithImage/>-->
	</xsl:if>
	<xsl:if test="name() = 'collection'">
	  <xsl:call-template name="collDescription"/><!--<gslib:collectionLinkWithImage/>-->
	</xsl:if>				
</xsl:template>

<!-- Modified version of <gslib:groupLinkWithImage/> for customising perrin interface -->
	<xsl:template name="customGroupDescription">
	  <xsl:variable name="short"><xsl:value-of select="shortDescription"/></xsl:variable>
	  <xsl:variable name="desc"><xsl:value-of select="description"/></xsl:variable>
	  <xsl:variable name="group_href"><xsl:value-of select="$library_name"/>/group/<xsl:if test="/page/pageRequest/paramList/param[@name='group']"><xsl:value-of select="/page/pageRequest/paramList/param[@name='group']/@value"/>/</xsl:if><xsl:value-of select="@name"/></xsl:variable>
	  
	  <!-- creates a header that links to the collection's about page -->
	  <!--group: <xsl:value-of select="@name"/>-->
	  <h2>
	    <a href="{$group_href}" title="{$short}">
	      <xsl:choose>
		<xsl:when test="boolean(title)">
		  <xsl:value-of select="title"/>
		</xsl:when>
		<xsl:otherwise>
		  <xsl:value-of select="@name"/>
		</xsl:otherwise>
	      </xsl:choose>
	    </a>
	  </h2>

	  <!-- if there is an image for this group, this is displayed -->
	  <xsl:choose>
	    <xsl:when test="util:checkFileExistence($site_name, backgroundImage)">
		<img class="groupLinkImage">
		  <xsl:attribute name="alt"><xsl:value-of select="@name"/></xsl:attribute>
		  <xsl:attribute name="src">sites/<xsl:value-of select="$site_name"/>/<xsl:value-of select="backgroundImage"/></xsl:attribute>
		  <xsl:attribute name="height">200px</xsl:attribute>
		  <xsl:attribute name="style">float:right</xsl:attribute>
		</img>
	    </xsl:when>	    
	  </xsl:choose>

	  <div style="clear:right">
	  <xsl:choose>
	    <!-- If the group has a description - display it -->
	    <xsl:when test="$desc">
              <!-- for supporting html in group description, see how the collection description
              is displayed in template name='collDescription' -->
	      <p class="justify"><xsl:value-of select="$desc" disable-output-escaping="yes"/></p>
	    </xsl:when>
	    <!-- If no group description - repeat group name -->
	    <xsl:otherwise>
	      <p class="justify">Collection group: <xsl:value-of select="@name" disable-output-escaping="yes"/></p>
	    </xsl:otherwise>
	  </xsl:choose>
	  </div>
	</xsl:template>

3. Save and close the file.
Any changes to groupConfig.xml would need a server restart to take effect. However, if you already restarted after editing groupConfig.xml, then you only need to refresh your browser to see the changes to home.xsl above in action.

Advanced: if laying out groups column-wise in table cells of an html table

There is some complexity if you want every 2 groups (or collections) appearing in a separate <div> or other element.

The following modifications to home.xsl will produce groups in a 2 rows by 3 column table, but laid out column-wise: the 1st column first, then 2nd column, then 3rd column, etc.

These modifications also optionally provide support for an additional column of standalone collections.

First follow the steps in the section Displaying Collection Groups above, then, edit web/interfaces/perrin/transform/pages/home.xsl as follows:

1. Locate:

<xsl:call-template name="collectionAndGroupLinks"/>

Replace with:

  <!-- <xsl:call-template name="collectionAndGroupLinks"/> --> 

  <!-- output the groups, the following outputs them column wise --> 
  <xsl:apply-templates select="groupList/group" mode="displayGroupInfo" /> 
  <!-- then output the collectionList in a final column --> 
  <xsl:apply-templates select="collectionList/collection" mode="displayCollInfo" /> 

2. Locate:

<xsl:template name="collDescription">

Replace with:

 <!-- 
   Template has match and name attributes allowing this to be called with both 
   apply-templates and call-template. 
   https://stackoverflow.com/questions/6478163/can-an-xslt-template-carry-both-name-and-match-attributes 
 --> 
 <xsl:template match="collection" name="collDescription" mode="displayColl"> 

3. Locate:

<xsl:template name="customGroupDescription">

Replace with:

 <!--  
 Template has match and name attributes allowing this to be called with both 
 apply-templates and call-template. 
 https://stackoverflow.com/questions/6478163/can-an-xslt-template-carry-both-name-and-match-attributes 
 --> 
 <xsl:template match="group" name="customGroupDescription"> 

4. Before the customGroupDescription template, now insert the following:

	<!-- To organise table cells, <td>, one column at a time:
        https://stackoverflow.com/questions/93511/counter-inside-xslfor-each-loop
	will not work, since we have an if-statement inside the for loop to filter for groups.
	Instead, counting only the groups using Borodin's solution (still xslt 1.0) from
	https://stackoverflow.com/questions/16504727/increment-counter-in-xslt-1-0 works.

	While that gives us a proper counter not dependent on position(), it doesn't solve
	that we need to open a tag (td) on odd count and close it on even.
	For that, the solution is at:
	https://stackoverflow.com/questions/17992481/xsl-wrap-every-2-items-in-the-for-each-with-a-div

	General: https://stackoverflow.com/questions/4478045/what-are-the-differences-between-call-template-and-apply-templates-in-xsl
	-->
	<xsl:template match="group" mode="displayGroupInfo">
	  <xsl:variable name="counter"><xsl:value-of select="1+count(preceding-sibling::group)])"/></xsl:variable>
	  <xsl:if test="($counter mod 2) = 1">
	    <td style="width:33.333333333333%; padding:0 15px;">
	      <xsl:apply-templates select=". |  following-sibling::group[1]" />
	      <!-- calls the template match="group" without mode this time -->
	    </td>
	  </xsl:if>
	</xsl:template>

	<!-- We want collections to appear in a separate and single column.
	     So we don't do even odd columns here. -->
	<xsl:template match="collection" mode="displayCollInfo">
	  <td style="width:33.333333333333%; padding:0 15px;">	      
	    <xsl:apply-templates select="." mode="displayColl"/>
	    <!-- why does calling the template match="collection" without some mode
	         attr this time NOT work? -->
	  </td>
	</xsl:template>	

If yo were to set a class attribute on the <td> cells above, you could move the styling for the <td> cells into a css file where you can also add additional styling to them.

1. Edit web/interfaces/perrin/transform/transform/layouts/main.xsl by locating:

<xsl:choose>
  <xsl:when test="$username">	   
    <xsl:if test="contains($groups,'admin')">
      <li class="login"><a href="{$library_name}/admin/AddUser">Add user</a></li>
      <li class="login"><a href="{$library_name}/admin/ListUsers">Administration</a></li>
    </xsl:if>
    ...

Immediately after <xsl:when test="$username"> in the above excerpt, add the following:

      <!-- Depositor link: only for logged-in users.
	CSS class=login to make Depositor link blue to indicate it's only available when logged in.
	Don't put this depositorTitleAndLink inside the test for whether user 'admin' is
	in the current list of groups, as we want the depositor link to be visible for any
	logged in user. The collection they want to deposit a doc into will determine whether
	that user has the right to modify that collection.
      -->
      <li class="login"><gslib:depositorTitleAndLink/></li>

2. Then copy the folder web/interfaces/default/transform/depositor into web/interfaces/transform/perrin.

This is because this folder is referred to from your web/interfaces/perrin/interfaceConfig.xml file:

  <action class="DepositorAction" name="de" xslt="pages/depositor_home.xsl">
    <subaction name="getwizard" xslt="depositor/compiledDepositor.xsl"/>
  </action>

3. Save and close the file.
Refresh your browser and login to see the Depositor link. The Depositor wizard's interface for perrin could do with some CSS styling. But the above changes brings the Depositor's functionality into the perin interface.

Displaying the document/section index level dropdown in the basic search form

By default, the visible search box does not provide a dropdown to search at document vs section level, even if there is more than one search level index available for a collection. It just searches within the default level index, and users would need to choose one of the form search options to have control over this.

With the following changes in place, if there is more than one search level index for a collection, a dropdown will be displayed near the default search box, allowing the user to choose at what index level to search. By default this dropdown would be set to the default search level index configured when the collection was built.

Edit web/interfaces/perrin/transform/transform/layouts/main.xsl as follows:

1. Comment out the code that hides index levels by replacing

		<input type="hidden" name="s1.level">
		  <xsl:attribute name="value">
		    <xsl:value-of select="/page/pageResponse/collection/serviceList/service[@name='TextQuery']/paramList/param[@name = 'level']/@default"/>
		  </xsl:attribute>
		</input>

with:

		<!-- don't hide indexing levels: code further down will hide it if there's only 1 indexing level.
		     Instead, display a dropdown if the collection's configured with more than 1 index level available -->
		<!--<input type="hidden" name="s1.level">
		  <xsl:attribute name="value">
		    <xsl:value-of select="/page/pageResponse/collection/serviceList/service[@name='TextQuery']/paramList/param[@name = 'level']/@default"/>
		  </xsl:attribute>
		</input>
		-->

2. Find:
<code><!-- The submit button (for TextQuery) -->

Insert the following before that line:

		<!-- The index level selection list. hideSingle=true to hide the dropdown if there's only 1 level (the default). -->						
		<xsl:if test="/page/pageResponse/collection[@name=$collNameChecked]/serviceList/service[@name='TextQuery']/paramList/param[@name='level']/@type = 'enum_single'">
		  <span class="textselect">
		    <xsl:apply-templates select="/page/pageResponse/collection[@name=$collNameChecked]/serviceList/service[@name='TextQuery']/paramList/param[@name='level']">
		      <xsl:with-param name="default">
			<xsl:apply-templates select="/page/pageResponse/collection[@name=$collNameChecked]/serviceList/service[@name='TextQuery']/paramList/param[@name='level']" mode="calculate-default"/>
		      </xsl:with-param>
		      <xsl:with-param name="hideSingle">true</xsl:with-param>
		      <xsl:with-param name="quickSearch">true</xsl:with-param>
		    </xsl:apply-templates>
		  </span>
		</xsl:if>							

3. Save and close the file.
Refresh your digital library page in your browser, visit a collection and look for the new dropdown in the basic search form area.

Collections tend to have text, fielded and advanced search forms turned on by default. The perrin interface provides links to these in a dropdown in the navigation bar for the collection.

If you wanted to display a horizontal line of links to these instead, then as follows:

1. Adjust web/interfaces/perrin/transform/transform/layouts/main.xsl as follows: Locate:

<br class="clear" />
<div id="advanced"><a href="{$library_name}/collection/{$collNameChecked}/search/TextQuery">advanced search</a></div>

Replace the above with:

      <!-- The list of other search types -->
      <div class="query-form-links">
	<ul>
	  <xsl:for-each select="/page/pageResponse/collection[@name=$collNameChecked]/serviceList/service[@type='query']">
	    <xsl:if test="/page/pageRequest/paramList/param[@name='qs']/@value = 1 or not(@name = /page/pageRequest/paramList/param[@name='s']/@value)">
	      <li class="ui-state-default ui-corner-all">
		    <a class="query-form-links">
		      <xsl:attribute name="href">
			<xsl:value-of select="$library_name"/>/collection/<xsl:value-of select="$collNameChecked"/>/search/<xsl:value-of select="@name"/>
		      </xsl:attribute>
		      <xsl:value-of select="displayItem[@name='name']"/>
		    </a>
	      </li>
	    </xsl:if>
	  </xsl:for-each>
	</ul>
      </div>

2. Change in web/interfaces/perrin/styles/gs3-core-min.css:

.col2{color:#FFFFFF; background-color:#F6F6F6;height:67px;}

By editing the 67px for height to 90px, so the same line now looks like:

.col2{color:#FFFFFF; background-color:#F6F6F6;height:90px;}

3. Edit main/trunk/model-interfaces-dev/opotiki/styles/layout.css by locating:

/* ----------------------------------------------Generalise------------------------------------- */

Add the following above that:

div.query-form-links{float:right;} 
div.query-form-links a{font-size:16px;background-color:transparent;} 
div.query-form-links li{display:inline;padding-left:10px} 
div.query-form-links ul{padding-right:20px;} 

4. Save and close the edited files.
Refresh your digital library page in your browser, visit a collection that supports multiple search forms and there should now be links under the default search form to the other search forms available.