Index: zpt/changeDocumentViewer.zpt
===================================================================
--- zpt/changeDocumentViewer.zpt	(revision 477)
+++ zpt/changeDocumentViewer.zpt	(revision 526)
@@ -18,4 +18,8 @@
         <p class="form-text">Access groups (separated by ',') that are considered local, i.e. when a ressource restricts access
         to one of these groups, local access to the ressource is granted.</p>
+        <p class="form-optional">Available Layers</p>
+        <p class="form-element"><input size="80" tal:attributes="value here/getAvailableLayersJson | nothing" name="availableLayers"></p>
+        <p class="form-text">List of available layers per view mode. JSON, one key per mode, null, or a list of layers per key.
+          Leave empty for autoconfiguration.</p>
         <p class="form-optional">Digilib base URL</p>
         <p class="form-element"><input size="80" tal:attributes="value here/digilibBaseUrl | nothing" name="digilibBaseUrl"></p>
Index: zpt/common_template.zpt
===================================================================
--- zpt/common_template.zpt	(revision 511)
+++ zpt/common_template.zpt	(revision 526)
@@ -67,4 +67,30 @@
   </metal:block>
 
+  <!-- toc type switcher -->
+  <metal:block metal:define-macro="toc_switcher">
+    <ul class="switcher">
+      <li tal:attributes="class python:test(tocMode=='thumbs', 'sel', None)"><a
+        tal:attributes="href python:here.getLink('tocMode','thumbs')">Thumbnails</a>
+      </li>
+      <li tal:attributes="class python:test(tocMode=='text', 'sel', None)"
+        tal:condition="python:docpath and docinfo.get('numTocEntries', None)">
+        <a tal:attributes="href python:here.getLink('tocMode','text')">Content</a>
+      </li>
+      <li tal:attributes="class python:test(tocMode=='figures', 'sel', None)"
+        tal:condition="python:docpath and docinfo.get('numFigureEntries', None)">
+        <a
+        tal:attributes="href python:here.getLink('tocMode','figures')">Figures</a>
+      </li>
+      <li tal:attributes="class python:test(tocMode=='concordance', 'sel', None)"
+        tal:condition="python:docpath and docinfo.get('pageNumbers', None)">
+        <a
+        tal:attributes="href python:here.getLink('tocMode','concordance')">Concordance</a>
+      </li>
+      <li tal:attributes="class python:test(tocMode=='none', 'sel', None)"><a
+        tal:attributes="href python:here.getLink('tocMode','none')">None</a>
+      </li>
+    </ul>
+  </metal:block>
+
 </body>
 </html>
Index: zpt/layer_text_annotator.zpt
===================================================================
--- zpt/layer_text_annotator.zpt	(revision 525)
+++ zpt/layer_text_annotator.zpt	(revision 526)
@@ -3,5 +3,5 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-<metal:block metal:define-macro="html_head">
+<metal:block metal:define-macro="html_head" tal:condition="python:'annotator' in viewLayers">
   <!--  annotator -->
   <link rel="stylesheet" type="text/css"
@@ -88,5 +88,5 @@
   </div>
 
-  <metal:block metal:define-macro="options_box">
+  <metal:block metal:define-macro="options_box" tal:condition="python:'annotator' in viewLayers">
     <!-- BEGIN ANNOTATIONS -->
     <div class="options">
Index: zpt/layer_text_dict.zpt
===================================================================
--- zpt/layer_text_dict.zpt	(revision 526)
+++ zpt/layer_text_dict.zpt	(revision 526)
@@ -0,0 +1,44 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<!-- not used here
+<metal:block metal:define-macro="html_head">
+</metal:block>
+-->
+</head>
+<body>
+  <!-- right-side options -->
+  <div class="col buttons">
+    <!-- LAYER DISPLAY OPTION  -->
+    <ul>
+      <metal:block metal:define-macro="layer_select_li">
+        <li>
+          <input type="checkbox" class="autosubmit" name="viewLayer" value="dict"
+            tal:attributes="checked python:'dict' in viewLayers" /> Dictionary
+        </li>
+      </metal:block>
+    </ul>
+  </div>
+
+  <metal:block metal:define-macro="options_box" tal:condition="python:'dict' in viewLayers">
+    <!--"BEGIN DICTIONARY OVERVIEW"-->
+    <div class="options">
+      <h4>Dictionary view</h4>
+      <form name="f3" action="">
+        <ul>
+          <li>
+            <input type="radio" name="r3" /> Tab
+          </li>
+          <li>
+            <input type="radio" name="r3" /> Window
+          </li>
+        </ul>
+      </form>
+    </div>
+    <!--"END DICTIONARY OVERVIEW"-->
+  </metal:block>
+
+</body>
+
+</html>
Index: zpt/layer_text_gis.zpt
===================================================================
--- zpt/layer_text_gis.zpt	(revision 525)
+++ zpt/layer_text_gis.zpt	(revision 526)
@@ -22,7 +22,7 @@
   </div>
 
-  <metal:block metal:define-macro="options_box">
+  <metal:block metal:define-macro="options_box" tal:condition="python:'gis' in viewLayers">
     <!--"BEGIN PLACES"-->
-    <div class="options" tal:condition="python:'gis' in viewLayers">
+    <div class="options">
       <tal:block
         tal:define="
Index: zpt/layer_text_search.zpt
===================================================================
--- zpt/layer_text_search.zpt	(revision 526)
+++ zpt/layer_text_search.zpt	(revision 526)
@@ -0,0 +1,90 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<metal:block metal:define-macro="html_head"
+  tal:define="
+    global query python:request.get('query', None); 
+    global queryType python:request.get('queryType','fulltextMorph');
+">
+</metal:block>
+</head>
+<body>
+  <!-- right-side options -->
+  <div class="col buttons">
+    <!-- LAYER DISPLAY OPTION  -->
+    <ul>
+      <metal:block metal:define-macro="layer_select_li">
+        <li tal:condition="python:query">
+          <input type="checkbox" class="autosubmit" name="viewLayer" value="search"
+            tal:attributes="checked python:'search' in viewLayers" /> Search hits
+        </li>
+      </metal:block>
+    </ul>
+  </div>
+
+  <metal:block metal:define-macro="extra_column" tal:condition="python:'search' in viewLayers">
+    <!-- right-side search results -->
+    <div class="col results" tal:condition="query">
+      <!--"BEGIN SEARCH RESULTS"  -->
+      <div class="options">
+        <h4>Search results</h4>
+        <div
+          tal:define="start pageinfo/resultStart; resultsize python:docinfo.get('resultSize',0); grpsize pageinfo/resultPageSize;
+                batch python:here.getBatch(start=start,size=grpsize,end=resultsize);">
+          <div class="ruler" tal:define="startParam string:resultStart">
+            <metal:block metal:use-macro="here/template/common_template/macros/toc_ruler" />
+          </div>
+          <div class="content"
+            tal:content="structure python:here.getResultsPage(mode=queryType,query=query,start=start,size=grpsize,pageinfo=pageinfo,docinfo=docinfo)" />
+        </div>
+      </div>
+    </div>
+  </metal:block>
+
+  <metal:block metal:define-macro="options_box">
+    <!--"BEGIN SEARCH"-->
+    <div class="options">
+      <h4>Search</h4>
+      <form tal:attributes="action viewerUrl">
+        <input type="hidden"
+          tal:define="params python:here.getParams(params={'query':None,'queryType':None,'viewLayer':None})"
+          tal:repeat="param params"
+          tal:attributes="name param; value python:params[param]" />
+        <!-- make sure we have one viewLayer=search -->
+        <tal:block tal:repeat="vl viewLayers">
+          <input type="hidden" name="viewLayer" tal:attributes="value vl"
+            tal:condition="python:vl != 'search'" />
+        </tal:block>
+        <input type="hidden" name="viewLayer" value="search" />
+        <!-- query text -->
+        <input type="text" name="query" tal:attributes="value query" /> <input
+          type="submit" value="Search" /> <a
+          tal:attributes="href python:here.getLink('query',None)">Clear</a>
+        <ul>
+          <li>
+            <input type="radio" name="queryType" value="fulltext"
+              tal:attributes="checked python:queryType=='fulltext'" /> Exact
+          </li>
+          <li>
+            <input type="radio" name="queryType" value="fulltextMorph"
+              tal:attributes="checked python:queryType=='fulltextMorph'" /> All forms
+          </li>
+          <li>
+            <input type="radio" name="queryType" value="ftIndex"
+              tal:attributes="checked python:queryType=='ftIndex'" /> Fulltext index
+          </li>
+          <li>
+            <input type="radio" name="queryType" value="ftIndexMorph"
+              tal:attributes="checked python:queryType=='ftIndexMorph'" /> Morphological
+            index
+          </li>
+        </ul>
+      </form>
+    </div>
+    <!--"END SEARCH"-->
+  </metal:block>
+
+</body>
+
+</html>
Index: zpt/search_template.zpt
===================================================================
--- zpt/search_template.zpt	(revision 511)
+++ 	(revision )
@@ -1,21 +1,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-</head>
-<body>
-  <!-- block used for main content area -->
-  <div metal:define-macro="results_div"
-    tal:define="start pageinfo/resultStart; resultsize python:docinfo.get('resultSize',0); grpsize pageinfo/resultPageSize;
-                batch python:here.getBatch(start=start,size=grpsize,end=resultsize);">
-    <div class="ruler" tal:define="startParam string:resultStart">
-        <metal:block metal:use-macro="here/template/common_template/macros/toc_ruler"/>
-    </div>
-    <div class="content"
-      tal:content="structure python:here.getResultsPage(mode=queryType,query=query,start=start,size=grpsize,pageinfo=pageinfo,docinfo=docinfo)" />
-  </div>
-<!--  tal:content="structure python:here.getResultsPage(mode=queryType,query=query,pn=1,pageinfo=pageinfo,docinfo=docinfo)" -->
-<!--  structure python:here.getTocPage(mode='text',start=start,pageinfo=pageinfo,docinfo=docinfo) -->
-</body>
-</html>
Index: zpt/toc_concordance.zpt
===================================================================
--- zpt/toc_concordance.zpt	(revision 526)
+++ zpt/toc_concordance.zpt	(revision 526)
@@ -0,0 +1,47 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+</head>
+<body>
+  <!-- block used for main content area -->
+  <div class="toc-concordance" metal:define-macro="main"
+    tal:define="start pageinfo/start; tocsize docinfo/numPages; grpsize pageinfo/tocPageSize;
+                pageNumbers docinfo/pageNumbers | nothing;
+                batch python:here.getBatch(start=start,size=grpsize,end=tocsize,data=pageNumbers);">
+    <div metal:use-macro="here/template/common_template/macros/toc_switcher" />
+    <div class="ruler">
+      <metal:block metal:use-macro="here/template/common_template/macros/toc_ruler" />
+    </div>
+    <div class="content">
+      <table tal:condition="pageNumbers">
+        <tr>
+          <th>Scan</th>
+          <th>Original</th>
+        </tr>
+        <tr tal:repeat="toc batch/this">
+          <tal:block tal:define="pn toc/pn | nothing">
+            <td>
+              <a tal:condition="pn"
+                tal:attributes="href python:here.getLink('pn', toc['pn'])"
+                tal:content="toc/pn" title="Scan number">ScanNo</a>
+            </td>
+            <td>
+              <span class="originalPage" title="Original page number"
+                tal:define="originalPage toc/no | nothing"
+                tal:condition="python:originalPage!=None"><span
+                tal:replace="originalPage" /><span
+                tal:define="originalPageNorm toc/non | nothing"
+                tal:condition="python:originalPageNorm!=None"> [<span
+                  tal:replace="originalPageNorm" />]
+              </span></span>
+            </td>
+          </tal:block>
+        </tr>
+      </table>
+    </div>
+  </div>
+  <!-- /toc -->
+</body>
+</html>
Index: zpt/toc_figures.zpt
===================================================================
--- zpt/toc_figures.zpt	(revision 518)
+++ zpt/toc_figures.zpt	(revision 526)
@@ -10,21 +10,5 @@
     tal:define="start pageinfo/start; tocsize docinfo/numFigureEntries; grpsize pageinfo/tocPageSize;
                 batch python:here.getBatch(start=start,size=grpsize,end=tocsize);">
-    <ul class="switcher">
-      <li><a
-        tal:attributes="href python:here.getLink('tocMode','thumbs')">Thumbnails</a>
-      </li>
-      <li
-        tal:condition="python:docpath and docinfo.get('numTocEntries', None)">
-        <a tal:attributes="href python:here.getLink('tocMode','text')">Content</a>
-      </li>
-      <li class="sel"
-        tal:condition="python:docpath and docinfo.get('numFigureEntries', None)">
-        <a
-        tal:attributes="href python:here.getLink('tocMode','figures')">Figures</a>
-      </li>
-      <li><a
-        tal:attributes="href python:here.getLink('tocMode','none')">None</a>
-      </li>
-    </ul>
+    <div metal:use-macro="here/template/common_template/macros/toc_switcher"/>
     <div class="ruler">
         <metal:block metal:use-macro="here/template/common_template/macros/toc_ruler"/>
@@ -33,5 +17,5 @@
       tal:content="structure python:here.getTocPage(mode='figures',start=start,pageinfo=pageinfo,docinfo=docinfo)" />
   </div>
-  <!-- toc -->
+  <!-- /toc -->
 </body>
 </html>
Index: zpt/toc_none.zpt
===================================================================
--- zpt/toc_none.zpt	(revision 491)
+++ zpt/toc_none.zpt	(revision 526)
@@ -8,18 +8,5 @@
   <!-- block used for main content area -->
   <div class="toc-none" metal:define-macro="main">
-    <ul class="switcher">
-      <li>
-        <a tal:attributes="href python:here.getLink('tocMode','thumbs')">Thumbnails</a>
-      </li>
-      <li tal:condition="python:docpath and docinfo.get('numTocEntries', None)">
-        <a tal:attributes="href python:here.getLink('tocMode','text')">Content</a>
-      </li>
-      <li tal:condition="python:docpath and docinfo.get('numFigureEntries', None)">
-        <a tal:attributes="href python:here.getLink('tocMode','figures')">Figures</a>
-      </li>
-      <li class="sel">
-        <a tal:attributes="href python:here.getLink('tocMode','none')">None</a>
-      </li>
-    </ul>
+    <div metal:use-macro="here/template/common_template/macros/toc_switcher"/>
     <div class="content"></div>
   </div>
Index: zpt/toc_text.zpt
===================================================================
--- zpt/toc_text.zpt	(revision 518)
+++ zpt/toc_text.zpt	(revision 526)
@@ -10,21 +10,5 @@
     tal:define="start pageinfo/start; tocsize docinfo/numTocEntries; grpsize pageinfo/tocPageSize;
                 batch python:here.getBatch(start=start,size=grpsize,end=tocsize);">
-    <ul class="switcher">
-      <li><a
-        tal:attributes="href python:here.getLink('tocMode','thumbs')">Thumbnails</a>
-      </li>
-      <li class="sel"
-        tal:condition="python:docpath and docinfo.get('numTocEntries', None)">
-        <a tal:attributes="href python:here.getLink('tocMode','text')">Content</a>
-      </li>
-      <li
-        tal:condition="python:docpath and docinfo.get('numFigureEntries', None)">
-        <a
-        tal:attributes="href python:here.getLink('tocMode','figures')">Figures</a>
-      </li>
-      <li><a
-        tal:attributes="href python:here.getLink('tocMode','none')">None</a>
-      </li>
-    </ul>
+    <div metal:use-macro="here/template/common_template/macros/toc_switcher"/>
     <div class="ruler">
         <metal:block metal:use-macro="here/template/common_template/macros/toc_ruler"/>
Index: zpt/toc_thumbs.zpt
===================================================================
--- zpt/toc_thumbs.zpt	(revision 523)
+++ zpt/toc_thumbs.zpt	(revision 526)
@@ -15,18 +15,5 @@
                 left python:test(flowLtr,pageBatch['prevStart'],pageBatch['nextStart']);
                 right python:test(flowLtr,pageBatch['nextStart'],pageBatch['prevStart']);">
-    <ul class="toctype">
-      <li class="sel">
-        <a tal:attributes="href python:here.getLink('tocMode','thumbs')">Thumbnails</a>
-      </li>
-      <li tal:condition="python:docinfo.get('numTocEntries', None)">
-        <a tal:attributes="href python:here.getLink('tocMode','text')">Content</a>
-      </li>
-      <li tal:condition="python:docinfo.get('numFigureEntries', None)">
-        <a tal:attributes="href python:here.getLink('tocMode','figures')">Figures</a>
-      </li>
-      <li>
-        <a tal:attributes="href python:here.getLink('tocMode','none')">None</a>
-      </li>
-    </ul>
+    <div metal:use-macro="here/template/common_template/macros/toc_switcher"/>
 
     <div class="content">
Index: zpt/viewer_text.zpt
===================================================================
--- zpt/viewer_text.zpt	(revision 525)
+++ zpt/viewer_text.zpt	(revision 526)
@@ -24,6 +24,6 @@
 // -->
 </script>
-<!--  layer headers -->
-<tal:block tal:repeat="layer viewLayers">
+<!--  layer headers (rendered always) -->
+<tal:block tal:repeat="layer availableLayers">
   <tal:block tal:define="mpath string:here/template/layer_text_${layer}/macros/html_head"
     tal:condition="python:exists(mpath)">
@@ -38,6 +38,4 @@
                 pn pageinfo/pn; 
                 flowLtr python:docinfo.get('pageFlow','ltr')!='rtl';
-                query python:request.get('query', None); 
-                queryType python:request.get('queryType','fulltextMorph');
                 textPage python:here.getTextPage(mode=viewLayer, pn=pn, docinfo=docinfo, pageinfo=pageinfo) or '[no text here]';">
     <!-- header -->
@@ -71,12 +69,11 @@
       <!-- end of col-main -->
 
-      <!-- right-side search results -->
-      <div class="col results" tal:condition="query">
-        <!--"BEGIN SEARCH RESULTS"  -->
-        <div class="options">
-          <h4>Search results</h4>
-          <div metal:use-macro="here/template/search_template/macros/results_div" />
-        </div>
-      </div>
+      <!--  layer columns (rendered always) -->
+      <tal:block tal:repeat="layer availableLayers">
+        <tal:block tal:define="mpath string:here/template/layer_text_${layer}/macros/extra_column"
+          tal:condition="python:exists(mpath)">
+          <metal:block metal:use-macro="python:path(mpath)" />
+        </tal:block>
+      </tal:block>
 
       <!-- right-side options -->
@@ -95,17 +92,5 @@
                   tal:attributes="checked python:viewMode=='text'" /> Text
                 <ul>
-                  <!-- text layers -->
-                  <li>
-                    <input type="checkbox" class="autosubmit" name="viewLayer"
-                      value="dict" tal:attributes="checked python:'dict' in viewLayers" />
-                    Dictionary
-                  </li>
-                  <li tal:condition="python:query">
-                    <input type="checkbox" class="autosubmit" name="viewLayer"
-                      value="search"
-                      tal:attributes="checked python:'search' in viewLayers" /> Search
-                    hits
-                  </li>
-                  <!-- auto-layer select buttons -->
+                  <!-- text layer select buttons (rendered always) -->
                   <tal:block tal:repeat="layer availableLayers">
                     <tal:block
@@ -127,45 +112,4 @@
         <!--"END TEXT DISPLAY"-->
 
-        <!--"BEGIN SEARCH"-->
-        <div class="options">
-          <h4>Search</h4>
-          <form tal:attributes="action viewerUrl">
-            <input type="hidden"
-              tal:define="params python:here.getParams(params={'query':None,'queryType':None,'viewLayer':None})"
-              tal:repeat="param params"
-              tal:attributes="name param; value python:params[param]" />
-            <!-- make sure we have one viewLayer=search -->
-            <tal:block tal:repeat="vl viewLayers">
-              <input type="hidden" name="viewLayer" tal:attributes="value vl"
-                tal:condition="python:vl != 'search'" />
-            </tal:block>
-            <input type="hidden" name="viewLayer" value="search" />
-            <!-- query text -->
-            <input type="text" name="query" tal:attributes="value query" /> <input
-              type="submit" value="Search" /> <a
-              tal:attributes="href python:here.getLink('query',None)">Clear</a>
-            <ul>
-              <li>
-                <input type="radio" name="queryType" value="fulltext"
-                  tal:attributes="checked python:queryType=='fulltext'" /> Exact
-              </li>
-              <li>
-                <input type="radio" name="queryType" value="fulltextMorph"
-                  tal:attributes="checked python:queryType=='fulltextMorph'" /> All forms
-              </li>
-              <li>
-                <input type="radio" name="queryType" value="ftIndex"
-                  tal:attributes="checked python:queryType=='ftIndex'" /> Fulltext index
-              </li>
-              <li>
-                <input type="radio" name="queryType" value="ftIndexMorph"
-                  tal:attributes="checked python:queryType=='ftIndexMorph'" />
-                Morphological index
-              </li>
-            </ul>
-          </form>
-        </div>
-        <!--"END SEARCH"-->
-
         <!--"BEGIN TEXT SIZE"-->
         <div class="options">
@@ -184,20 +128,4 @@
         </div>
         <!--"END TEXT SIZE"-->
-
-        <!--"BEGIN DICTIONARY OVERVIEW"-->
-        <div class="options" tal:condition="python:'dict' in viewLayers">
-          <h4>Dictionary view</h4>
-          <form name="f3" action="">
-            <ul>
-              <li>
-                <input type="radio" name="r3" /> Tab
-              </li>
-              <li>
-                <input type="radio" name="r3" /> Window
-              </li>
-            </ul>
-          </form>
-        </div>
-        <!--"END DICTIONARY OVERVIEW"-->
 
         <!--"BEGIN TEXT NORMALIZATION"-->
@@ -230,6 +158,6 @@
         <!--"END TEXT NORMALIZATION"-->
 
-        <!--  auto-layer option boxes -->
-        <tal:block tal:repeat="layer viewLayers">
+        <!--  layer option boxes (rendered if active) -->
+        <tal:block tal:repeat="layer availableLayers">
           <tal:block
             tal:define="mpath string:here/template/layer_text_${layer}/macros/options_box"
