about summary refs log tree commit diff
path: root/uploader/templates
diff options
context:
space:
mode:
Diffstat (limited to 'uploader/templates')
-rw-r--r--uploader/templates/base.html180
-rw-r--r--uploader/templates/cli-output.html4
-rw-r--r--uploader/templates/expression-data/base.html13
-rw-r--r--uploader/templates/expression-data/data-review.html (renamed from uploader/templates/data_review.html)6
-rw-r--r--uploader/templates/expression-data/index.html82
-rw-r--r--uploader/templates/expression-data/job-progress.html (renamed from uploader/templates/job_progress.html)9
-rw-r--r--uploader/templates/expression-data/no-such-job.html (renamed from uploader/templates/no_such_job.html)3
-rw-r--r--uploader/templates/expression-data/parse-failure.html (renamed from uploader/templates/parse_failure.html)0
-rw-r--r--uploader/templates/expression-data/parse-results.html39
-rw-r--r--uploader/templates/expression-data/select-file.html115
-rw-r--r--uploader/templates/expression-data/select-population.html29
-rw-r--r--uploader/templates/genotypes/base.html11
-rw-r--r--uploader/templates/genotypes/create-dataset.html82
-rw-r--r--uploader/templates/genotypes/index.html4
-rw-r--r--uploader/templates/genotypes/list-genotypes.html40
-rw-r--r--uploader/templates/genotypes/list-markers.html5
-rw-r--r--uploader/templates/genotypes/select-population.html16
-rw-r--r--uploader/templates/genotypes/view-dataset.html61
-rw-r--r--uploader/templates/index.html140
-rw-r--r--uploader/templates/jobs/job-error.html17
-rw-r--r--uploader/templates/jobs/job-not-found.html11
-rw-r--r--uploader/templates/jobs/job-status.html24
-rw-r--r--uploader/templates/login.html7
-rw-r--r--uploader/templates/macro-step-indicator.html15
-rw-r--r--uploader/templates/macro-table-pagination.html26
-rw-r--r--uploader/templates/parse_results.html30
-rw-r--r--uploader/templates/phenotypes/add-phenotypes-base.html166
-rw-r--r--uploader/templates/phenotypes/add-phenotypes-raw-files.html847
-rw-r--r--uploader/templates/phenotypes/add-phenotypes-with-rqtl2-bundle.html207
-rw-r--r--uploader/templates/phenotypes/base.html19
-rw-r--r--uploader/templates/phenotypes/bulk-edit-upload.html62
-rw-r--r--uploader/templates/phenotypes/create-dataset.html108
-rw-r--r--uploader/templates/phenotypes/edit-phenotype.html208
-rw-r--r--uploader/templates/phenotypes/index.html21
-rw-r--r--uploader/templates/phenotypes/job-status.html155
-rw-r--r--uploader/templates/phenotypes/list-datasets.html68
-rw-r--r--uploader/templates/phenotypes/load-phenotypes-success.html42
-rw-r--r--uploader/templates/phenotypes/macro-display-pheno-dataset-card.html31
-rw-r--r--uploader/templates/phenotypes/macro-display-preview-table.html19
-rw-r--r--uploader/templates/phenotypes/macro-display-resumable-elements.html60
-rw-r--r--uploader/templates/phenotypes/review-job-data.html125
-rw-r--r--uploader/templates/phenotypes/select-population.html26
-rw-r--r--uploader/templates/phenotypes/view-dataset.html150
-rw-r--r--uploader/templates/phenotypes/view-phenotype.html135
-rw-r--r--uploader/templates/platforms/base.html13
-rw-r--r--uploader/templates/platforms/create-platform.html124
-rw-r--r--uploader/templates/platforms/index.html25
-rw-r--r--uploader/templates/platforms/list-platforms.html93
-rw-r--r--uploader/templates/populations/base.html6
-rw-r--r--uploader/templates/populations/create-population.html53
-rw-r--r--uploader/templates/populations/index.html4
-rw-r--r--uploader/templates/populations/list-populations.html2
-rw-r--r--uploader/templates/populations/macro-display-population-card.html39
-rw-r--r--uploader/templates/populations/macro-select-population.html72
-rw-r--r--uploader/templates/populations/rqtl2/create-tissue-success.html (renamed from uploader/templates/rqtl2/create-tissue-success.html)0
-rw-r--r--uploader/templates/populations/rqtl2/index.html54
-rw-r--r--uploader/templates/populations/rqtl2/no-such-job.html (renamed from uploader/templates/rqtl2/no-such-job.html)0
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-job-error.html (renamed from uploader/templates/rqtl2/rqtl2-job-error.html)0
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-job-results.html (renamed from uploader/templates/rqtl2/rqtl2-job-results.html)0
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-job-status.html (renamed from uploader/templates/rqtl2/rqtl2-job-status.html)0
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-qc-job-error.html (renamed from uploader/templates/rqtl2/rqtl2-qc-job-error.html)0
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-qc-job-results.html (renamed from uploader/templates/rqtl2/rqtl2-qc-job-results.html)0
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-qc-job-status.html (renamed from uploader/templates/rqtl2/rqtl2-qc-job-status.html)0
-rw-r--r--uploader/templates/populations/rqtl2/rqtl2-qc-job-success.html (renamed from uploader/templates/rqtl2/rqtl2-qc-job-success.html)0
-rw-r--r--uploader/templates/populations/rqtl2/select-geno-dataset.html69
-rw-r--r--uploader/templates/populations/rqtl2/select-population.html57
-rw-r--r--uploader/templates/populations/rqtl2/select-probeset-dataset.html (renamed from uploader/templates/rqtl2/select-probeset-dataset.html)0
-rw-r--r--uploader/templates/populations/rqtl2/select-probeset-study-id.html (renamed from uploader/templates/rqtl2/select-probeset-study-id.html)0
-rw-r--r--uploader/templates/populations/rqtl2/select-tissue.html (renamed from uploader/templates/rqtl2/select-tissue.html)0
-rw-r--r--uploader/templates/populations/rqtl2/summary-info.html (renamed from uploader/templates/rqtl2/summary-info.html)0
-rw-r--r--uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-01.html (renamed from uploader/templates/rqtl2/upload-rqtl2-bundle-step-01.html)0
-rw-r--r--uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-02.html (renamed from uploader/templates/rqtl2/upload-rqtl2-bundle-step-02.html)0
-rw-r--r--uploader/templates/populations/view-population.html26
-rw-r--r--uploader/templates/publications/base.html12
-rw-r--r--uploader/templates/publications/create-publication.html191
-rw-r--r--uploader/templates/publications/index.html100
-rw-r--r--uploader/templates/publications/view-publication.html78
-rw-r--r--uploader/templates/rqtl2/create-geno-dataset-success.html55
-rw-r--r--uploader/templates/rqtl2/create-probe-dataset-success.html59
-rw-r--r--uploader/templates/rqtl2/create-probe-study-success.html49
-rw-r--r--uploader/templates/rqtl2/index.html36
-rw-r--r--uploader/templates/rqtl2/select-geno-dataset.html144
-rw-r--r--uploader/templates/rqtl2/select-population.html136
-rw-r--r--uploader/templates/samples/index.html4
-rw-r--r--uploader/templates/samples/list-samples.html38
-rw-r--r--uploader/templates/samples/select-population.html23
-rw-r--r--uploader/templates/samples/upload-failure.html2
-rw-r--r--uploader/templates/samples/upload-samples.html2
-rw-r--r--uploader/templates/select_species.html92
-rw-r--r--uploader/templates/species/base.html5
-rw-r--r--uploader/templates/species/create-species.html112
-rw-r--r--uploader/templates/species/list-species.html2
-rw-r--r--uploader/templates/species/macro-display-species-card.html18
-rw-r--r--uploader/templates/species/macro-select-species.html83
-rw-r--r--uploader/templates/species/view-species.html6
95 files changed, 4267 insertions, 1035 deletions
diff --git a/uploader/templates/base.html b/uploader/templates/base.html
index 171e8fa..3c0d0d4 100644
--- a/uploader/templates/base.html
+++ b/uploader/templates/base.html
@@ -8,14 +8,14 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     {%block extrameta%}{%endblock%}
 
-    <title>GN Uploader: {%block title%}{%endblock%}</title>
+    <title>Data Upload and Quality Control: {%block title%}{%endblock%}</title>
 
     <link rel="stylesheet" type="text/css"
 	  href="{{url_for('base.bootstrap',
                 filename='css/bootstrap.min.css')}}" />
     <link rel="stylesheet" type="text/css"
-	  href="{{url_for('base.bootstrap',
-                filename='css/bootstrap-theme.min.css')}}" />
+          href="{{url_for('base.datatables',
+                filename='css/dataTables.bootstrap5.min.css')}}" />
     <link rel="stylesheet" type="text/css" href="/static/css/styles.css" />
 
     {%block css%}{%endblock%}
@@ -23,83 +23,139 @@
   </head>
 
   <body>
-    <header id="header" class="container-fluid">
-      <div class="row">
-        <span class="header col-lg-9">GeneNetwork Data Quality Control and Upload</span>
-        <nav class="header-nav col-lg-3">
-          <ul class="nav justify-content-end">
-            <li>
-              {%if user_logged_in()%}
-              <a href="{{url_for('oauth2.logout')}}"
-                 title="Log out of the system">{{user_email()}} &mdash; Log Out</a>
-              {%else%}
-              <a href="{{authserver_authorise_uri()}}"
-                 title="Log in to the system">Log In</a>
-              {%endif%}
-            </li>
-          </ul>
-        </nav>
+    <header id="header">
+      <span id="header-text">GeneNetwork</span>
+      <nav id="header-nav">
+        <ul class="nav justify-content-end">
+          <li>
+            {%if user_logged_in()%}
+            <a href="{{url_for('oauth2.logout')}}"
+               title="Log out of the system">
+              <span class="glyphicon glyphicon-user"></span>
+              {{user_email()}} Sign Out</a>
+            {%else%}
+            <a href="{{authserver_authorise_uri()}}"
+               title="Log in to the system">Sign In</a>
+            {%endif%}
+          </li>
+        </ul>
+      </nav>
     </header>
 
-    <aside id="nav-sidebar" class="container-fluid">
+    <aside id="nav-sidebar">
       <ul class="nav flex-column">
-        <li><a href="/" >Home</a></li>
-        <li><a href="{{url_for('species.list_species')}}"
-               title="View and manage species information.">Species</a></li>
-        <li><a href="{{url_for('species.populations.index')}}"
-               title="View and manage species populations.">Populations</a></li>
-        <li><a href="{{url_for('species.populations.samples.index')}}"
-               title="Upload population samples.">Samples</a></li>
-        <li><a href="{{url_for('species.populations.genotypes.index')}}"
-               title="Upload Genotype data.">Genotype Data</a></li>
-        <li><a href="{{url_for('expression-data.index.index')}}"
-               title="Upload expression data.">Expression Data</a></li>
-        <li><a href="#"
-               title="Upload phenotype data.">Phenotype Data</a></li>
-        <li><a href="#"
-               title="Upload individual data.">Individual Data</a></li>
-        <li><a href="#"
-               title="Upload RNA-Seq data.">RNA-Seq Data</a></li>
+        <li {%if activemenu=="home"%}class="activemenu"{%endif%}>
+          <a href="/" >Home</a></li>
+        <li {%if activemenu=="publications"%}class="activemenu"{%endif%}>
+          <a href="{{url_for('publications.index')}}"
+             title="View and manage publications.">Publications</a></li>
+        <li {%if activemenu=="species"%}class="activemenu"{%endif%}>
+          <a href="{{url_for('species.list_species')}}"
+             title="View and manage species information.">Species</a></li>
+        <li {%if activemenu=="platforms"%}class="activemenu"{%endif%}>
+          <a href="{{url_for('species.platforms.index')}}"
+             title="View and manage species platforms.">Sequencing Platforms</a></li>
+        <li {%if activemenu=="populations"%}class="activemenu"{%endif%}>
+          <a href="{{url_for('species.populations.index')}}"
+             title="View and manage species populations.">Populations</a></li>
+        <li {%if activemenu=="samples"%}class="activemenu"{%endif%}>
+          <a href="{{url_for('species.populations.samples.index')}}"
+             title="Upload population samples.">Samples</a></li>
+        <li {%if activemenu=="genotypes"%}class="activemenu"{%endif%}>
+          <a href="{{url_for('species.populations.genotypes.index')}}"
+             title="Upload Genotype data.">Genotype Data</a></li>
+        <!--
+            TODO: Maybe include menus here for managing studies and dataset or
+            maybe have the studies/datasets managed under their respective
+            sections, e.g. "Publish*" studies/datasets under the "Phenotypes"
+            section, "ProbeSet*" studies/datasets under the "Expression Data"
+            sections, etc.
+          -->
+        <li {%if activemenu=="phenotypes"%}class="activemenu"{%endif%}>
+          <a href="{{url_for('species.populations.phenotypes.index')}}"
+             title="Upload phenotype data.">Phenotype Data</a></li>
+        <!--
+        <li {%if activemenu=="expression-data"%}class="activemenu"{%endif%}>
+          <a href="{{url_for('species.populations.expression-data.index')}}"
+             title="Upload expression data."
+             class="not-implemented">Expression Data</a></li>
+        <li {%if activemenu=="individuals"%}class="activemenu"{%endif%}>
+          <a href="#"
+             class="not-implemented"
+             title="Upload individual data.">Individual Data</a></li>
+        <li {%if activemenu=="rna-seq"%}class="activemenu"{%endif%}>
+          <a href="#"
+             class="not-implemented"
+             title="Upload RNA-Seq data.">RNA-Seq Data</a></li>
+        <li {%if activemenu=="async-jobs"%}class="activemenu"{%endif%}>
+          <a href="#"
+             class="not-implemented"
+             title="View and manage the backgroud jobs you have running">
+            Background Jobs</a></li>
+        -->
       </ul>
     </aside>
 
-    <main id="main" class="main container-fluid">
+    <main id="main" class="main">
 
-      <div class="pagetitle row">
-        <h1>GN Uploader: {%block pagetitle%}{%endblock%}</h1>
-        <nav>
-          <ol class="breadcrumb">
-            <li {%if activelink is not defined or activelink=="home"%}
-                class="breadcrumb-item active"
-                {%else%}
-                class="breadcrumb-item"
-                {%endif%}>
-              <a href="{{url_for('base.index')}}">Home</a>
-            </li>
-            {%block lvl1_breadcrumbs%}{%endblock%}
-          </ol>
-        </nav>
+      <div id="pagetitle" class="pagetitle">
+        <span class="title">Data Upload and Quality Control: {%block pagetitle%}{%endblock%}</span>
+        <!--
+            <nav>
+              <ol class="breadcrumb">
+                <li {%if activelink is not defined or activelink=="home"%}
+                    class="breadcrumb-item active"
+                    {%else%}
+                    class="breadcrumb-item"
+                    {%endif%}>
+                  <a href="{{url_for('base.index')}}">Home</a>
+                </li>
+                {%block lvl1_breadcrumbs%}{%endblock%}
+              </ol>
+            </nav>
+            -->
       </div>
 
-      <div class="row">
-        <div class="container-fluid">
-          <div class="col-md-8 main-content">
-            {%block contents%}{%endblock%}
-          </div>
-          <div class="sidebar-content col-md-4">
-            {%block sidebarcontents%}{%endblock%}
-          </div>
+      <div id="all-content">
+        <div id="main-content">
+          {%block contents%}{%endblock%}
+        </div>
+        <div id="sidebar-content">
+          {%block sidebarcontents%}{%endblock%}
         </div>
       </div>
     </main>
 
 
+    <!--
+        Core dependencies
+      -->
     <script src="{{url_for('base.jquery',
                  filename='jquery.min.js')}}"></script>
     <script src="{{url_for('base.bootstrap',
                  filename='js/bootstrap.min.js')}}"></script>
-    {%block javascript%}{%endblock%}
 
-  </body>
+    <!--
+        DataTables dependencies
+      -->
+    <script type="text/javascript"
+            src="{{url_for('base.datatables',
+                 filename='js/dataTables.min.js')}}"></script>
+    <script type="text/javascript"
+        src="{{url_for('base.datatables_extensions',
+             filename='scroller/js/dataTables.scroller.min.js')}}"></script>
+    <script type="text/javascript"
+            src="{{url_for('base.datatables_extensions',
+                 filename='buttons/js/dataTables.buttons.min.js')}}"></script>
+    <script type="text/javascript"
+            src="{{url_for('base.datatables_extensions',
+                 filename='select/js/dataTables.select.min.js')}}"></script>
 
+    <!--
+        local dependencies
+      -->
+    <script type="text/javascript" src="/static/js/utils.js"></script>
+    <script type="text/javascript" src="/static/js/datatables.js"></script>
+    {%block javascript%}{%endblock%}
+  </body>
 </html>
diff --git a/uploader/templates/cli-output.html b/uploader/templates/cli-output.html
index 33fb73b..64b1a9a 100644
--- a/uploader/templates/cli-output.html
+++ b/uploader/templates/cli-output.html
@@ -1,7 +1,7 @@
 {%macro cli_output(job, stream)%}
 
-<h4>{{stream | upper}} Output</h4>
-<div class="cli-output">
+<h4 class="subheading">{{stream | upper}} Output</h4>
+<div class="cli-output" style="max-height: 10em; overflow: auto;">
   <pre>{{job.get(stream, "")}}</pre>
 </div>
 
diff --git a/uploader/templates/expression-data/base.html b/uploader/templates/expression-data/base.html
new file mode 100644
index 0000000..d63fd7e
--- /dev/null
+++ b/uploader/templates/expression-data/base.html
@@ -0,0 +1,13 @@
+{%extends "populations/base.html"%}
+
+{%block lvl3_breadcrumbs%}
+<li {%if activelink=="expression-data"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.expression-data.index')}}">
+    Expression Data</a>
+</li>
+{%block lvl4_breadcrumbs%}{%endblock%}
+{%endblock%}
diff --git a/uploader/templates/data_review.html b/uploader/templates/expression-data/data-review.html
index 4e5c586..c985b03 100644
--- a/uploader/templates/data_review.html
+++ b/uploader/templates/expression-data/data-review.html
@@ -26,7 +26,7 @@
           <small class="text-muted">
             If you encounter an error saying your sample(s)/case(s) do not exist
             in the GeneNetwork database, then you will have to use the
-            <a href="{{url_for('expression-data.samples.select_species')}}"
+            <a href="{{url_for('species.populations.samples.index')}}"
                title="Upload samples/cases feature">Upload Samples/Cases</a>
             option on this system to upload them.
           </small>
@@ -70,8 +70,8 @@
 	  column</li>
 	<li>The values of each field <strong>ARE NOT</strong> quoted.</li>
 	<li>Here is an
-	  <a href="https://gitlab.com/fredmanglis/gnqc_py/-/blob/main/tests/test_data/no_data_errors.tsv">
-	    example file</a> with a single data row.</li>
+	  <a href="https://gitlab.com/fredmanglis/gnqc_py/-/blob/main/tests/test_data/no_data_errors.tsv"
+             target="_blank">example file</a> with a single data row.</li>
       </ul>
     </li>
     <li>.txt files: Content has the same format as .tsv file above</li>
diff --git a/uploader/templates/expression-data/index.html b/uploader/templates/expression-data/index.html
index ed5d8dd..9ba3582 100644
--- a/uploader/templates/expression-data/index.html
+++ b/uploader/templates/expression-data/index.html
@@ -1,5 +1,6 @@
-{%extends "base.html"%}
+{%extends "expression-data/base.html"%}
 {%from "flash_messages.html" import flash_all_messages%}
+{%from "species/macro-select-species.html" import select_species_form%}
 
 {%block title%}Expression Data{%endblock%}
 
@@ -10,86 +11,23 @@
   <a href="{{url_for('base.index')}}">Home</a>
 </li>
 <li class="breadcrumb-item active">
-  <a href="{{url_for('expression-data.index.index')}}">Expression Data</a>
+  <a href="{{url_for('species.populations.expression-data.index')}}"
+     title="Upload expression data.">
+    Expression Data</a>
 </li>
 {%endblock%}
 
 {%block contents%}
 <div class="row">
-  {{flash_all_messages()}}
-
-  <h1 class="heading">data upload</h1>
-
-  <div class="explainer">
-    <p>Each of the sections below gives you a different option for data expression-data.
-      Please read the documentation for each section carefully to understand what
-      each section is about.</p>
-  </div>
-</div>
-
-<div class="row">
-  <h2 class="heading">R/qtl2 Bundles</h2>
-
-  <div class="explainer">
-    <p>This feature combines and extends the two upload methods below. Instead of
-      uploading one item at a time, the R/qtl2 bundle you upload can contain both
-      the genotypes data (samples/individuals/cases and their data) and the
-      expression data.</p>
-    <p>The R/qtl2 bundle, additionally, can contain extra metadata, that neither
-      of the methods below can handle.</p>
-
-    <a href="{{url_for('expression-data.rqtl2.select_species')}}"
-       title="Upload a zip bundle of R/qtl2 files">
-      <button class="btn btn-primary">upload R/qtl2 bundle</button></a>
-  </div>
-</div>
-
-
-<div class="row">
   <h2 class="heading">Expression Data</h2>
+  {{flash_all_messages()}}
 
-  <div class="explainer">
-    <p>This feature enables you to upload expression data. It expects the data to
-      be in <strong>tab-separated values (TSV)</strong> files. The data should be
-      a simple matrix of <em>phenotype × sample</em>, i.e. The first column is a
-      list of the <em>phenotypes</em> and the first row is a list of
-      <em>samples/cases</em>.</p>
-
-    <p>If you haven't done so please go to this page to learn the requirements for
-      file formats and helpful suggestions to enter your data in a fast and easy
-      way.</p>
-
-    <ol>
-      <li><strong>PLEASE REVIEW YOUR DATA.</strong>Make sure your data complies
-        with our system requirements. (
-        <a href="{{url_for('expression-data.index.data_review')}}#data-concerns"
-	   title="Details for the data expectations.">Help</a>
-        )</li>
-      <li><strong>UPLOAD YOUR DATA FOR DATA VERIFICATION.</strong> We accept
-        <strong>.csv</strong>, <strong>.txt</strong> and <strong>.zip</strong>
-        files (<a href="{{url_for('expression-data.index.data_review')}}#file-types"
-	          title="Details for the data expectations.">Help</a>)</li>
-    </ol>
-  </div>
-
-  <a href="{{url_for('expression-data.index.upload_file')}}"
-     title="Upload your expression data"
-     class="btn btn-primary">upload expression data</a>
+  <p>This section allows you to enter the expression data for your experiment.
+    You will need to select the species that your data concerns below.</p>
 </div>
 
 <div class="row">
-  <h2 class="heading">samples/cases</h2>
-
-  <div class="explainer">
-    <p>For the expression data above, you need the samples/cases in your file to
-      already exist in the GeneNetwork database. If there are any samples that do
-      not already exist the upload of the expression data will fail.</p>
-    <p>This section gives you the opportunity to upload any missing samples</p>
-  </div>
-
-  <a href="{{url_for('expression-data.samples.select_species')}}"
-     title="Upload samples/cases/individuals for your data"
-     class="btn btn-primary">upload Samples/Cases</a>
+  {{select_species_form(url_for("species.populations.expression-data.index"),
+  species)}}
 </div>
-
 {%endblock%}
diff --git a/uploader/templates/job_progress.html b/uploader/templates/expression-data/job-progress.html
index 2feaa89..ef264e1 100644
--- a/uploader/templates/job_progress.html
+++ b/uploader/templates/expression-data/job-progress.html
@@ -1,5 +1,6 @@
 {%extends "base.html"%}
 {%from "errors_display.html" import errors_display%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
 
 {%block extrameta%}
 <meta http-equiv="refresh" content="5">
@@ -11,7 +12,9 @@
 <h1 class="heading">{{job_name}}</h2>
 
 <div class="row">
-  <form action="{{url_for('expression-data.parse.abort')}}" method="POST">
+  <form action="{{url_for('species.populations.expression-data.abort',
+                species_id=species.SpeciesId,
+                population_id=population.Id)}}" method="POST">
     <legend class="heading">Status</legend>
     <div class="form-group">
       <label for="job_status" class="form-label">status:</label>
@@ -38,3 +41,7 @@
 </div>
 
 {%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/no_such_job.html b/uploader/templates/expression-data/no-such-job.html
index 874d047..d22c429 100644
--- a/uploader/templates/no_such_job.html
+++ b/uploader/templates/expression-data/no-such-job.html
@@ -1,7 +1,8 @@
 {%extends "base.html"%}
 
 {%block extrameta%}
-<meta http-equiv="refresh" content="5;url={{url_for('expression-data.index.upload_file')}}">
+<meta http-equiv="refresh"
+      content="5;url={{url_for('species.populations.expression-data.index.upload_file')}}">
 {%endblock%}
 
 {%block title%}No Such Job{%endblock%}
diff --git a/uploader/templates/parse_failure.html b/uploader/templates/expression-data/parse-failure.html
index 31f6be8..31f6be8 100644
--- a/uploader/templates/parse_failure.html
+++ b/uploader/templates/expression-data/parse-failure.html
diff --git a/uploader/templates/expression-data/parse-results.html b/uploader/templates/expression-data/parse-results.html
new file mode 100644
index 0000000..03a23e2
--- /dev/null
+++ b/uploader/templates/expression-data/parse-results.html
@@ -0,0 +1,39 @@
+{%extends "base.html"%}
+{%from "errors_display.html" import errors_display%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Parse Results{%endblock%}
+
+{%block contents%}
+
+<div class="row">
+  <h2 class="heading">{{job_name}}: parse results</h2>
+
+  {%if user_aborted%}
+  <span class="alert-warning">Job aborted by the user</span>
+  {%endif%}
+
+  {{errors_display(errors, "No errors found in the file", "We found the following errors", True)}}
+
+  {%if errors | length == 0 and not user_aborted %}
+  <form method="post" action="{{url_for('dbinsert.select_platform')}}">
+    <input type="hidden" name="job_id" value="{{job_id}}" />
+    <input type="submit" value="update database" class="btn btn-primary" />
+  </form>
+  {%endif%}
+
+  {%if errors | length > 0 or user_aborted %}
+  <br />
+  <a href="{{url_for('species.populations.expression-data.upload_file',
+           species_id=species.SpeciesId,
+           population_id=population.Id)}}"
+     title="Back to index page."
+     class="btn btn-primary">Go back</a>
+
+  {%endif%}
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/expression-data/select-file.html b/uploader/templates/expression-data/select-file.html
new file mode 100644
index 0000000..4ca461e
--- /dev/null
+++ b/uploader/templates/expression-data/select-file.html
@@ -0,0 +1,115 @@
+{%extends "expression-data/base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+{%from "upload_progress_indicator.html" import upload_progress_indicator%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Expression Data &mdash; Upload Data{%endblock%}
+
+{%block pagetitle%}Expression Data &mdash; Upload Data{%endblock%}
+
+{%block contents%}
+{{upload_progress_indicator()}}
+
+<div class="row">
+  <h2 class="heading">Upload Expression Data</h2>
+
+  <p>This feature enables you to upload expression data. It expects the data to
+    be in <strong>tab-separated values (TSV)</strong> files. The data should be
+    a simple matrix of <em>phenotype × sample</em>, i.e. The first column is a
+    list of the <em>phenotypes</em> and the first row is a list of
+    <em>samples/cases</em>.</p>
+
+  <p>If you haven't done so please go to this page to learn the requirements for
+    file formats and helpful suggestions to enter your data in a fast and easy
+    way.</p>
+
+  <ol>
+    <li><strong>PLEASE REVIEW YOUR DATA.</strong>Make sure your data complies
+      with our system requirements. (
+      <a href="{{url_for('species.populations.expression-data.data_review')}}#data-concerns"
+	 title="Details for the data expectations.">Help</a>
+      )</li>
+    <li><strong>UPLOAD YOUR DATA FOR DATA VERIFICATION.</strong> We accept
+      <strong>.csv</strong>, <strong>.txt</strong> and <strong>.zip</strong>
+      files (<a href="{{url_for('species.populations.expression-data.data_review')}}#file-types"
+	        title="Details for the data expectations.">Help</a>)</li>
+  </ol>
+</div>
+
+<div class="row">
+  <form action="{{url_for(
+                'species.populations.expression-data.upload_file',
+                species_id=species.SpeciesId,
+                population_id=population.Id)}}"
+        method="POST"
+        enctype="multipart/form-data"
+        id="frm-upload-expression-data">
+    {{flash_messages("error-expr-data")}}
+
+    <div class="form-group">
+      <legend class="heading">File Type</legend>
+
+      <div class="radio">
+        <label for="filetype_average" class="form-check-label">
+          <input type="radio" name="filetype" value="average" id="filetype_average"
+	         required="required" class="form-check-input" />
+          Average</label>
+        <p class="form-text text-muted">
+          <small>The averages data …</small></p>
+      </div>
+
+      <div class="radio">
+        <label for="filetype_standard_error" class="form-check-label">
+          <input type="radio" name="filetype" value="standard-error"
+	         id="filetype_standard_error" required="required"
+	         class="form-check-input" />
+          Standard Error
+        </label>
+        <p class="form-text text-muted">
+          <small>The standard errors computed from the averages …</small></p>
+      </div>
+    </div>
+
+    <div class="form-group">
+      <span id="no-file-error" class="alert-danger" style="display: none;">
+        No file selected
+      </span>
+      <label for="file_upload" class="form-label">Select File</label>
+      <input type="file" name="qc_text_file" id="file_upload"
+	     accept="text/plain, text/tab-separated-values, application/zip"
+	     class="form-control"/>
+      <p class="form-text text-muted">
+        <small>Select the file to upload.</small></p>
+    </div>
+
+    <button type="submit"
+            class="btn btn-primary"
+            data-toggle="modal"
+            data-target="#upload-progress-indicator">upload file</button>
+  </form>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/upload_progress.js"></script>
+<script type="text/javascript">
+  function setup_formdata(form) {
+      var formdata = new FormData();
+      formdata.append(
+	  "qc_text_file",
+	  form.querySelector("input[type='file']").files[0]);
+      formdata.append(
+	  "filetype",
+	  selected_filetype(
+	      Array.from(form.querySelectorAll("input[type='radio']"))));
+      return formdata;
+  }
+
+  setup_upload_handlers(
+      "frm-upload-expression-data", make_data_uploader(setup_formdata));
+</script>
+{%endblock%}
diff --git a/uploader/templates/expression-data/select-population.html b/uploader/templates/expression-data/select-population.html
new file mode 100644
index 0000000..8555e27
--- /dev/null
+++ b/uploader/templates/expression-data/select-population.html
@@ -0,0 +1,29 @@
+{%extends "expression-data/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "species/macro-display-species-card.html" import display_species_card%}
+{%from "populations/macro-select-population.html" import select_population_form%}
+
+{%block title%}Expression Data{%endblock%}
+
+{%block pagetitle%}Expression Data{%endblock%}
+
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <p>You have selected the species. Now you need to select the population that
+  the expression data belongs to.</p>
+</div>
+
+<div class="row">
+  {{select_population_form(url_for(
+  "species.populations.expression-data.select_population",
+  species_id=species.SpeciesId),
+  populations)}}
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_species_card(species)}}
+{%endblock%}
diff --git a/uploader/templates/genotypes/base.html b/uploader/templates/genotypes/base.html
index 1b274bf..7d61312 100644
--- a/uploader/templates/genotypes/base.html
+++ b/uploader/templates/genotypes/base.html
@@ -6,7 +6,18 @@
     {%else%}
     class="breadcrumb-item"
     {%endif%}>
+  {%if population is mapping%}
+  <a href="{{url_for('species.populations.genotypes.list_genotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id)}}">
+    {%if dataset is defined and dataset is mapping%}
+    {{dataset.Name}}
+    {%else%}
+    Genotypes
+    {%endif%}</a>
+  {%else%}
   <a href="{{url_for('species.populations.genotypes.index')}}">Genotypes</a>
+  {%endif%}
 </li>
 {%block lvl4_breadcrumbs%}{%endblock%}
 {%endblock%}
diff --git a/uploader/templates/genotypes/create-dataset.html b/uploader/templates/genotypes/create-dataset.html
new file mode 100644
index 0000000..10331c1
--- /dev/null
+++ b/uploader/templates/genotypes/create-dataset.html
@@ -0,0 +1,82 @@
+{%extends "genotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Genotypes — Create Dataset{%endblock%}
+
+{%block pagetitle%}Genotypes — Create Dataset{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="create-dataset"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.genotypes.create_dataset',
+           species_id=species.SpeciesId,
+           population_id=population.Id)}}">Create Dataset</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <form id="frm-geno-create-dataset"
+        method="POST"
+        action="{{url_for('species.populations.genotypes.create_dataset',
+                species_id=species.SpeciesId,
+                population_id=population.Id)}}">
+    <legend>Create a new Genotype Dataset</legend>
+
+    <div class="form-group">
+      <label for="txt-geno-dataset-name" class="form-label">Name</label>
+      <input type="text"
+             id="txt-geno-dataset-name"
+             name="geno-dataset-name"
+             required="required"
+             class="form-control" />
+      <small class="form-text text-muted">
+        <p>This is a short representative, but constrained name for the genotype
+          dataset.<br />
+          The field will only accept letters ('A-Za-z'), numbers (0-9), hyphens
+          and underscores. Any other character will cause the name to be
+          rejected.</p></small>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-geno-dataset-fullname" class="form-label">Full Name</label>
+      <input type="text"
+             id="txt-geno-dataset-fullname"
+             name="geno-dataset-fullname"
+             required="required"
+             class="form-control" />
+      <small class="form-text text-muted">
+        <p>This is a longer, more descriptive name for your dataset.</p></small>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-geno-dataset-shortname"
+             class="form-label">Short Name</label>
+      <input type="text"
+             id="txt-geno-dataset-shortname"
+             name="geno-dataset-shortname"
+             class="form-control" />
+      <small class="form-text text-muted">
+        <p>A short name for your dataset. If you leave this field blank, the
+          short name will be set to the same value as the
+          "<strong>Name</strong>" field above.</p></small>
+    </div>
+
+    <div class="form-group">
+      <input type="submit"
+             class="btn btn-primary"
+             value="create dataset"  />
+    </div>
+  </form>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/genotypes/index.html b/uploader/templates/genotypes/index.html
index e749f5a..b50ebc5 100644
--- a/uploader/templates/genotypes/index.html
+++ b/uploader/templates/genotypes/index.html
@@ -26,3 +26,7 @@
   species)}}
 </div>
 {%endblock%}
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/species.js"></script>
+{%endblock%}
diff --git a/uploader/templates/genotypes/list-genotypes.html b/uploader/templates/genotypes/list-genotypes.html
index 8afd591..0f074fd 100644
--- a/uploader/templates/genotypes/list-genotypes.html
+++ b/uploader/templates/genotypes/list-genotypes.html
@@ -26,7 +26,8 @@
   <p>There are a total of {{total_markers}} currently registered genetic markers
     for the "{{species.FullName}}" species. You can click
     <a href="{{url_for('species.populations.genotypes.list_markers',
-             species_id=species.SpeciesId)}}"
+             species_id=species.SpeciesId,
+             population_id=population.Id)}}"
        title="View genetic markers for species '{{species.FullName}}">
       this link to view the genetic markers
     </a>.
@@ -70,7 +71,7 @@
   {%if genocode | length < 1%}
   <a href="#add-genotype-encoding"
      title="Add a genotype encoding system for this population"
-     class="btn btn-primary">
+     class="btn btn-primary not-implemented">
     add genotype encoding
     </a>
   {%endif%}
@@ -95,14 +96,8 @@
   <p>The genotype data is organised under various genotype datasets. You can
     click on the link for the relevant dataset to view a little more information
     about it.</p>
-  <p>You can also create a new genotype dataset by clicking the button below.
-    <br />
-    <a href="#create-new-genotype-dataset"
-       title="Create a new genotype dataset for the '{{population.FullName}}' population for the '{{species.FullName}}' species."
-       class="btn btn-primary">
-      create new genotype dataset</a></p>
 
-  {%if datasets | length > 0%}
+  {%if dataset is not none%}
     <table class="table">
       <thead>
         <tr>
@@ -112,7 +107,6 @@
       </thead>
 
       <tbody>
-        {%for dataset in datasets%}
         <tr>
           <td>{{dataset.Name}}</td>
           <td><a href="{{url_for('species.populations.genotypes.view_dataset',
@@ -122,16 +116,32 @@
                  title="View details regarding and manage dataset '{{dataset.FullName}}'">
               {{dataset.FullName}}</a></td>
         </tr>
-        {%endfor%}
       </tbody>
     </table>
   {%else%}
-    <p class="text-warning">
-      <span class="glyphicon glyphicon-exclamation-sign"></span>
-      There are no genotype datasets to display, yet!
-    </p>
+  <p class="text-warning">
+    <span class="glyphicon glyphicon-exclamation-sign"></span>
+    There is no genotype dataset defined for this population.
+  </p>
+  <p>
+    <a href="{{url_for('species.populations.genotypes.create_dataset',
+             species_id=species.SpeciesId,
+             population_id=population.Id)}}"
+       title="Create a new genotype dataset for the '{{population.FullName}}' population for the '{{species.FullName}}' species."
+       class="btn btn-primary">
+      create new genotype dataset</a></p>
   {%endif%}
 </div>
+<div class="row text-warning">
+  <p>
+    <span class="glyphicon glyphicon-exclamation-sign"></span>
+    <strong>NOTE</strong>: Currently the GN2 (and related) system(s) expect a
+    single genotype dataset. If there is more than one, the system apparently
+    fails in unpredictable ways.
+  </p>
+  <p>Fix this to allow multiple datasets, each with a different assembly from
+    all the rest.</p>
+</div>
 {%endblock%}
 
 {%block sidebarcontents%}
diff --git a/uploader/templates/genotypes/list-markers.html b/uploader/templates/genotypes/list-markers.html
index 9198b44..a705ae3 100644
--- a/uploader/templates/genotypes/list-markers.html
+++ b/uploader/templates/genotypes/list-markers.html
@@ -13,7 +13,8 @@
     class="breadcrumb-item"
     {%endif%}>
   <a href="{{url_for('species.populations.genotypes.list_markers',
-           species_id=species.SpeciesId)}}">List markers</a>
+           species_id=species.SpeciesId,
+           population_id=population.Id)}}">List markers</a>
 </li>
 {%endblock%}
 
@@ -30,6 +31,7 @@
       {%if start_from > 0%}
       <a href="{{url_for('species.populations.genotypes.list_markers',
                species_id=species.SpeciesId,
+               population_id=population.Id,
                start_from=start_from-count,
                count=count)}}">
         <span class="glyphicon glyphicon-backward"></span>
@@ -45,6 +47,7 @@
       {%if start_from + count < total_markers%}
       <a href="{{url_for('species.populations.genotypes.list_markers',
                species_id=species.SpeciesId,
+               population_id=population.Id,
                start_from=start_from+count,
                count=count)}}">
         Next
diff --git a/uploader/templates/genotypes/select-population.html b/uploader/templates/genotypes/select-population.html
index 7c81943..acdd063 100644
--- a/uploader/templates/genotypes/select-population.html
+++ b/uploader/templates/genotypes/select-population.html
@@ -12,20 +12,14 @@
 {{flash_all_messages()}}
 
 <div class="row">
-  <p>
-    You have indicated that you intend to upload the genotypes for species
-    '{{species.FullName}}'. We now just require the population for your
-    experiment/study, and you should be good to go.
-  </p>
-</div>
-
-<div class="row">
-  {{select_population_form(url_for("species.populations.genotypes.select_population",
-  species_id=species.SpeciesId),
-  populations)}}
+  {{select_population_form(url_for("species.populations.genotypes.select_population", species_id=species.SpeciesId), species, populations)}}
 </div>
 {%endblock%}
 
 {%block sidebarcontents%}
 {{display_species_card(species)}}
 {%endblock%}
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/populations.js"></script>
+{%endblock%}
diff --git a/uploader/templates/genotypes/view-dataset.html b/uploader/templates/genotypes/view-dataset.html
new file mode 100644
index 0000000..e7ceb36
--- /dev/null
+++ b/uploader/templates/genotypes/view-dataset.html
@@ -0,0 +1,61 @@
+{%extends "genotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Genotypes: View Dataset{%endblock%}
+
+{%block pagetitle%}Genotypes: View Dataset{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="view-dataset"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.genotypes.view_dataset',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">view dataset</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <h2>Genotype Dataset Details</h2>
+  <table class="table">
+    <thead>
+      <tr>
+        <th>Name</th>
+        <th>Full Name</th>
+      </tr>
+    </thead>
+
+    <tbody>
+      <tr>
+        <td>{{dataset.Name}}</td>
+        <td>{{dataset.FullName}}</td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+
+<div class="row text-warning">
+  <h2>Assembly Details</h2>
+
+  <p>Maybe include the assembly details here if found to be necessary.</p>
+</div>
+
+<div class="row">
+  <h2>Genotype Data</h2>
+
+  <p class="text-danger">
+    Provide link to enable uploading of genotype data here.</p>
+</div>
+
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/index.html b/uploader/templates/index.html
index 48848a3..aa1414e 100644
--- a/uploader/templates/index.html
+++ b/uploader/templates/index.html
@@ -5,101 +5,103 @@
 
 {%block pagetitle%}Home{%endblock%}
 
-{%block breadcrumb%}
-<li class="breadcrumb-item active">
-  <a href="{{url_for('base.index')}}">Home</a>
-</li>
-{%endblock%}
-
 {%block contents%}
 
 <div class="row">
   {{flash_all_messages()}}
   <div class="explainer">
-    <p>Welcome to the <strong>GeneNetwork Data Quality Control and Upload System</strong>. This system is provided to help in uploading your data onto GeneNetwork where you can do analysis on it.</p>
+    <p>Welcome to the <strong>GeneNetwork Data Upload and Quality Control
+        System</strong>.</p>
+    <p>This tool helps you prepare and upload research data to GeneNetwork for
+      analysis.</p>
 
-    <p>The sections below provide an overview of what features the menu items on
-      the left provide to you. Please peruse the information to get a good
-      big-picture understanding of what the system provides you and how to get
-      the most out of it.</p>
+    <h2 class="heading">Getting Started</h2>
+    <p>The sections below explain the features of the system. Review this guide
+      to learn how to use the system.</p>
 
     {%block extrapageinfo%}{%endblock%}
 
-    <h2>Species</h2>
-
-    <p>The GeneNetwork service provides datasets and tools for doing genetic
-      studies &mdash; from
-      <a href="{{gn2server_intro}}"
-         target="_blank"
-         title="GeneNetwork introduction — opens in a new tab.">
-        its introduction</a>:
-
-      <blockquote class="blockquote">
-        <p>GeneNetwork is a group of linked data sets and tools used to study
-          complex networks of genes, molecules, and higher order gene function
-          and phenotypes. &hellip;</p>
-      </blockquote>
-    </p>
-
-    <p>With this in mind, it follows that the data in the system is centered
-      aroud a variety of species. The <strong>species section</strong> will
-      list the currently available species in the system, and give you the
-      ability to add new ones, if the one you want to work on does not currently
-      exist on GeneNetwork</p>
-
-    <h2>Populations</h2>
-
-    <p>Your studies will probably focus on a particular subset of the entire
-      species you are interested in &ndash; your population.</p>
-    <p>Populations are a way to organise the species data so as to link data to
-      specific know populations for a particular species, e.g. The BXD
-      population of mice (Mus musculus)</p>
-    <p>In older GeneNetwork documentation, you might run into the term
-      <em>InbredSet</em>. Should you run into it, it is a term that we've
-      deprecated that essentially just means the population.</p>
-
-    <h2>Samples</h2>
-
-    <p>These are the samples or individuals (sometimes cases) that were involved
-      in the experiment, and from whom the data was derived.</p>
-
-    <h2>Genotype Data</h2>
-
-    <p>This section will allow you to view and upload the genetic markers for
-      your species, and the genotype encodings used for your particular
-      population.</p>
-    <p>While, technically, genetic markers relate to the species in general, and
-      not to a particular population, the data (allele information) itself
-      relates to the particular population it was generated from &ndash;
-      specifically, to the actual individuals used in the experiment.</p>
-    <p>This is the reason why the genotype data information comes under the
-      population, and will check for the prior existence of the related
-      samples/individuals before attempting an upload of your data.</p>
-
-    <h2>Expression Data</h2>
+    <h3 class="subheading">Species</h3>
 
-    <p class="text-danger">
-      <span class="glyphicon glyphicon-exclamation-sign"></span>
-      <strong>TODO</strong>: Document this &hellip;</p>
+    <p>GeneNetwork supports genetic studies across multiple species (e.g. mice
+      [Mus musculus], human [homo sapiens], rats [Rattus norvegicus], etc.) .
+      Here you can:</p>
+    <ul>
+      <li>View all species that are currently supported</li>
+      <li>Add new species not yet in the system</li>
+    </ul>
+
+    <h3 class="subheading">Populations</h3>
+
+    <p>A "population" refers to a specific subgroup within a species that you’re
+      studying (e.g., BXD mice). Here you can:</p>
+    <ul>
+      <li>View the populations that exist for a selected species</li>
+      <li>Add new populations of study for a selected species</li>
+    </ul>
+
+    <h3 class="subheading">Samples</h3>
+
+    <p>Manage individual specimens or cases used in your experiments. These
+      include:</p>
+
+    <ul>
+      <li>Experimental subjects</li>
+      <li>Data sources (e.g., tissue samples, clinical cases)</li>
+      <li>Strain means (instead of entering multiple BXD1 individuals, for
+        example, the mean would be entered for a single BXD1 strain)</li>
+    </ul>
+
+
+    <h3 class="subheading">Genotype Data</h3>
+
+    <p>Upload and review genetic markers and allele encodings for your
+      population. Key details:</p>
+
+    <ul>
+      <li>Markers are species-level (e.g., mouse SNP databases).</li>
+      <li>Allele data is population-specific (tied to your experimental
+        samples).</li>
+    </ul>
+
+    <p><strong>Requirement</strong>: Samples must already have been registered
+      in the system before uploading genotype data.</p>
+
+    <h3 class="subheading">Phenotype Data</h3>
+
+    <p>Phenotypes are the visible traits or features of a living thing. For
+      example, phenotypes include:</p>
+
+    <ul>
+      <li>Weight</li>
+      <li>Height</li>
+      <li>Color (such as the color of fur or eyes)</li>
+    </ul>
+
+    <p>This part of the system will allow you to upload and manage the values
+      for different phenotypes from various samples in your studies.</p>
+
+    <!--
 
-    <h2>Phenotype Data</h2>
+        <h3 class="subheading">Expression Data</h3>
 
     <p class="text-danger">
       <span class="glyphicon glyphicon-exclamation-sign"></span>
       <strong>TODO</strong>: Document this &hellip;</p>
 
-    <h2>Individual Data</h2>
+    <h3 class="subheading">Individual Data</h3>
 
     <p class="text-danger">
       <span class="glyphicon glyphicon-exclamation-sign"></span>
       <strong>TODO</strong>: Document this &hellip;</p>
 
-    <h2>RNA-Seq Data</h2>
+    <h3 class="subheading">RNA-Seq Data</h3>
 
     <p class="text-danger">
       <span class="glyphicon glyphicon-exclamation-sign"></span>
       <strong>TODO</strong>: Document this &hellip;</p>
   </div>
+  -->
 </div>
 
 {%endblock%}
diff --git a/uploader/templates/jobs/job-error.html b/uploader/templates/jobs/job-error.html
new file mode 100644
index 0000000..b3015fc
--- /dev/null
+++ b/uploader/templates/jobs/job-error.html
@@ -0,0 +1,17 @@
+{%extends "base.html"%}
+
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}Background Jobs: Error{%endblock%}
+
+{%block pagetitle%}Background Jobs: Error{%endblock%}
+
+{%block contents%}
+
+<h1>Background Jobs: Error</h1>
+<p>Job <strong>{{job["job_id"]}}</strong> failed!</p>
+<p>The error details are in the "STDERR" section below.</p>
+
+<h2>STDERR</h2>
+<pre>{{job["stderr"]}}</pre>
+{%endblock%}
diff --git a/uploader/templates/jobs/job-not-found.html b/uploader/templates/jobs/job-not-found.html
new file mode 100644
index 0000000..a71e66f
--- /dev/null
+++ b/uploader/templates/jobs/job-not-found.html
@@ -0,0 +1,11 @@
+{%extends "base.html"%}
+
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}Background Jobs{%endblock%}
+
+{%block pagetitle%}Background Jobs{%endblock%}
+
+{%block contents%}
+<p>Could not find job with ID: {{job_id}}</p>
+{%endblock%}
diff --git a/uploader/templates/jobs/job-status.html b/uploader/templates/jobs/job-status.html
new file mode 100644
index 0000000..83c02fd
--- /dev/null
+++ b/uploader/templates/jobs/job-status.html
@@ -0,0 +1,24 @@
+{%extends "base.html"%}
+
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block extrameta%}
+<meta http-equiv="refresh" content="5" />
+{%endblock%}
+
+{%block title%}Background Jobs{%endblock%}
+
+{%block pagetitle%}Background Jobs{%endblock%}
+
+{%block contents%}
+
+<p>Status: {{job["metadata"]["status"]}}</p>
+<p>Job Type: {{job["metadata"]["job-type"]}}</p>
+
+<h2>STDOUT</h2>
+<pre>{{job["stdout"]}}</pre>
+
+<h2>STDERR</h2>
+<pre>{{job["stderr"]}}</pre>
+
+{%endblock%}
diff --git a/uploader/templates/login.html b/uploader/templates/login.html
index 1f71416..e76c644 100644
--- a/uploader/templates/login.html
+++ b/uploader/templates/login.html
@@ -5,7 +5,8 @@
 {%block pagetitle%}log in{%endblock%}
 
 {%block extrapageinfo%}
-<p class="text-dark text-primary">
-  You <strong>do need to be logged in</strong> to upload data onto this system.
-  Please do that by clicking the "Log In" button at the top of the page.</p>
+<p class="text-dark">
+  You <strong>need to
+    <a href="{{authserver_authorise_uri()}}"
+       title="Sign in to the system">sign in</a></strong> to use this system.</p>
 {%endblock%}
diff --git a/uploader/templates/macro-step-indicator.html b/uploader/templates/macro-step-indicator.html
new file mode 100644
index 0000000..ac0be77
--- /dev/null
+++ b/uploader/templates/macro-step-indicator.html
@@ -0,0 +1,15 @@
+{%macro step_indicator(step, width=100)%}
+<svg width="{{width}}" height="{{width}}" xmlns="http://www.w3.org/2000/svg">
+  <circle cx="{{0.5*width}}"
+          cy="{{0.5*width}}"
+          r="{{0.5*width}}"
+          fill="#E5E5FF" />
+  <text x="{{0.5*width}}"
+        y="{{0.6*width}}"
+        font-size="{{0.2*width}}"
+        text-anchor="middle"
+        fill="#555555">
+    Step {{step}}
+  </text>
+</svg>
+{%endmacro%}
diff --git a/uploader/templates/macro-table-pagination.html b/uploader/templates/macro-table-pagination.html
new file mode 100644
index 0000000..292c531
--- /dev/null
+++ b/uploader/templates/macro-table-pagination.html
@@ -0,0 +1,26 @@
+{%macro table_pagination(start_at, page_count, total_count, base_uri, name)%}
+{%set ns = namespace(forward_uri=base_uri, back_uri=base_uri)%}
+{%set ns.forward_uri="brr"%}
+  <div class="row">
+    <div class="col-md-2" style="text-align: start;">
+      {%if start_at > 0%}
+      <a href="{{base_uri +
+               '?start_at='+((start_at-page_count)|string) +
+               '&count='+(page_count|string)}}">
+                 <span class="glyphicon glyphicon-backward"></span>
+                 Previous
+        </a>
+      {%endif%}
+    </div>
+    <div class="col-md-8" style="text-align: center;">
+      Displaying {{name}} {{start_at+1}} to {{start_at+page_count if start_at+page_count < total_count else total_count}} of {{total_count}}</div>
+      <div class="col-md-2" style="text-align: end;">
+        {%if start_at + page_count < total_count%}
+        <a href="{{base_uri +
+                 '?start_at='+((start_at+page_count)|string) +
+                 '&count='+(page_count|string)}}">
+            Next<span class="glyphicon glyphicon-forward"></span></a>
+        {%endif%}
+      </div>
+  </div>
+{%endmacro%}
diff --git a/uploader/templates/parse_results.html b/uploader/templates/parse_results.html
deleted file mode 100644
index 46fbaaf..0000000
--- a/uploader/templates/parse_results.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{%extends "base.html"%}
-{%from "errors_display.html" import errors_display%}
-
-{%block title%}Parse Results{%endblock%}
-
-{%block contents%}
-<h1 class="heading">{{job_name}}: parse results</h2>
-
-{%if user_aborted%}
-<span class="alert-warning">Job aborted by the user</span>
-{%endif%}
-
-{{errors_display(errors, "No errors found in the file", "We found the following errors", True)}}
-
-{%if errors | length == 0 and not user_aborted %}
-<form method="post" action="{{url_for('dbinsert.select_platform')}}">
-  <input type="hidden" name="job_id" value="{{job_id}}" />
-  <input type="submit" value="update database" class="btn btn-primary" />
-</form>
-{%endif%}
-
-{%if errors | length > 0 or user_aborted %}
-<br />
-<a href="{{url_for('expression-data.index.upload_file')}}" title="Back to index page."
-   class="btn btn-primary">
-  Go back
-</a>
-{%endif%}
-
-{%endblock%}
diff --git a/uploader/templates/phenotypes/add-phenotypes-base.html b/uploader/templates/phenotypes/add-phenotypes-base.html
new file mode 100644
index 0000000..9909c20
--- /dev/null
+++ b/uploader/templates/phenotypes/add-phenotypes-base.html
@@ -0,0 +1,166 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "phenotypes/macro-display-pheno-dataset-card.html" import display_pheno_dataset_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="add-phenotypes"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">Add Phenotypes</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <form id="frm-add-phenotypes"
+        method="POST"
+        enctype="multipart/form-data"
+        action="{{url_for('species.populations.phenotypes.add_phenotypes',
+                species_id=species.SpeciesId,
+                population_id=population.Id,
+                dataset_id=dataset.Id,
+                use_bundle=use_bundle)}}"
+        data-resumable-target="{{url_for('files.resumable_upload_post')}}">
+    <legend>Add New Phenotypes</legend>
+
+    <div class="form-text help-block">
+      {%block frm_add_phenotypes_documentation%}{%endblock%}
+      <p><strong class="text-warning">This will not update any existing phenotypes!</strong></p>
+    </div>
+
+    {%block frm_add_phenotypes_elements%}{%endblock%}
+
+    <fieldset id="fldset-publication-info">
+      <legend>Publication Information</legend>
+      <input type="hidden" name="publication-id" id="txt-publication-id" />
+      <span class="form-text text-muted">
+        Select a publication for your data. <br />
+        Can't find a publication you can use? Go ahead and
+        <a href="{{url_for(
+                 'publications.create_publication',
+                 return_to='species.populations.phenotypes.add_phenotypes',
+                 species_id=species.SpeciesId,
+                 population_id=population.Id,
+                 dataset_id=dataset.Id)}}">create a new publication</a>.</span>
+      <table id="tbl-select-publication" class="table compact stripe">
+        <thead>
+          <tr>
+            <th>#</th>
+            <th>PubMed ID</th>
+            <th>Title</th>
+            <th>Authors</th>
+          </tr>
+        </thead>
+
+        <tbody></tbody>
+      </table>
+    </fieldset>
+
+    <div class="form-group">
+      <input type="submit"
+             value="upload phenotypes"
+             class="btn btn-primary" />
+    </div>
+  </form>
+</div>
+
+<div class="row">
+  {%block page_documentation%}{%endblock%}
+</div>
+
+{%endblock%}
+
+
+{%block javascript%}
+<script type="text/javascript">
+  $(function() {
+      var publicationsDataTable = buildDataTable(
+          "#tbl-select-publication",
+          [],
+          [
+              {data: "index"},
+              {
+                  searchable: true,
+                  data: (pub) => {
+                      if(pub.PubMed_ID) {
+                          return `<a href="https://pubmed.ncbi.nlm.nih.gov/` +
+                              `${pub.PubMed_ID}/" target="_blank" ` +
+                              `title="Link to publication on NCBI.">` +
+                              `${pub.PubMed_ID}</a>`;
+                      }
+                      return "";
+                  }
+              },
+              {
+                  searchable: true,
+                  data: (pub) => {
+                      var title = "⸻";
+                      if(pub.Title) {
+                          title = pub.Title
+                      }
+                      return `<a href="/publications/view/${pub.Id}" ` +
+                          `target="_blank" ` +
+                          `title="Link to view publication details">` +
+                          `${title}</a>`;
+                  }
+              },
+              {
+                  searchable: true,
+                  data: (pub) => {
+                      authors = pub.Authors.split(",").map(
+                          (item) => {return item.trim();});
+                      if(authors.length > 1) {
+                          return authors[0] + ", et. al.";
+                      }
+                      return authors[0];
+                  }
+              }
+          ],
+          {
+              serverSide: true,
+              ajax: {
+                  url: "/publications/list",
+                  dataSrc: "publications"
+              },
+              select: "single",
+              paging: true,
+              scrollY: 700,
+              deferRender: true,
+              scroller: true,
+              scrollCollapse: true,
+              layout: {
+                  topStart: "info",
+                  topEnd: "search"
+              }
+          });
+      publicationsDataTable.on("select", (event, datatable, type, indexes) => {
+          indexes.forEach((element, index, thearray) => {
+              let row = datatable.row(element).node();
+              console.debug(datatable.row(element).data());
+              $("#frm-add-phenotypes #txt-publication-id").val(
+                  datatable.row(element).data().Id);
+          });
+      });
+      publicationsDataTable.on("deselect", (event, datatable, type, indexes) => {
+          indexes.forEach((element, index, thearray) => {
+              let row = datatable.row(element).node();
+              $("#frm-add-phenotypes #txt-publication-id").val(null);
+          });
+      });
+  });
+</script>
+
+{%block more_javascript%}{%endblock%}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/add-phenotypes-raw-files.html b/uploader/templates/phenotypes/add-phenotypes-raw-files.html
new file mode 100644
index 0000000..67b56e3
--- /dev/null
+++ b/uploader/templates/phenotypes/add-phenotypes-raw-files.html
@@ -0,0 +1,847 @@
+{%extends "phenotypes/add-phenotypes-base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "phenotypes/macro-display-pheno-dataset-card.html" import display_pheno_dataset_card%}
+{%from "phenotypes/macro-display-preview-table.html" import display_preview_table%}
+{%from "phenotypes/macro-display-resumable-elements.html" import display_resumable_elements%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="add-phenotypes"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">Add Phenotypes</a>
+</li>
+{%endblock%}
+
+{%block frm_add_phenotypes_documentation%}
+<p>This page will allow you to upload all the separate files that make up your
+  phenotypes. Here, you will have to upload each separate file individually. If
+  you want instead to upload all your files as a single ZIP file,
+  <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id,
+           use_bundle=true)}}"
+     title="">click here</a>.</p>
+{%endblock%}
+
+{%block frm_add_phenotypes_elements%}
+<fieldset id="fldset-file-metadata">
+  <legend>File(s) Metadata</legend>
+  <div class="form-group">
+    <label for="txt-file-separator" class="form-label">File Separator</label>
+    <div class="input-group">
+      <input id="txt-file-separator"
+             name="file-separator"
+             type="text"
+             value="&#9;"
+             class="form-control"
+             maxlength="1" />
+      <span class="input-group-btn">
+        <button id="btn-reset-file-separator" class="btn btn-info">Reset Default</button>
+      </span>
+    </div>
+    <span class="form-text text-muted">
+      Provide the character that separates the fields in your file(s). It should
+      be the same character for all files (if more than one is provided).<br />
+      A tab character will be assumed if you leave this field blank. See
+      <a href="#docs-file-separator"
+         title="Documentation for file-separator characters">
+        documentation for more information</a>.
+    </span>
+  </div>
+
+  <div class="form-group">
+    <label for="txt-file-comment-character" class="form-label">File Comment-Character</label>
+    <div class="input-group">
+      <input id="txt-file-comment-character"
+             name="file-comment-character"
+             type="text"
+             value="#"
+             class="form-control"
+             maxlength="1" />
+      <span class="input-group-btn">
+        <button id="btn-reset-file-comment-character" class="btn btn-info">
+          Reset Default</button>
+      </span>
+    </div>
+    <span class="form-text text-muted">
+      This specifies that lines that begin with the character provided will be
+      considered comment lines and ignored in their entirety. See
+      <a href="#docs-file-comment-character"
+         title="Documentation for comment characters">
+        documentation for more information</a>.
+    </span>
+  </div>
+
+  <div class="form-group">
+    <label for="txt-file-na" class="form-label">File "No-Value" Indicators</label>
+    <div class="input-group">
+      <input id="txt-file-na"
+             name="file-na"
+             type="text"
+             value="- NA N/A"
+             class="form-control" />
+      <span class="input-group-btn">
+        <button id="btn-reset-file-na" class="btn btn-info">Reset Default</button>
+      </span>
+    </div>
+    <span class="form-text text-muted">
+      This specifies strings in your file indicate that there is no value for a
+      particular cell (a cell is where a column and row intersect). Provide a
+      space-separated list of strings if you have more than one way of
+      indicating no values. See
+      <a href="#docs-file-na" title="Documentation for no-value fields">
+        documentation for more information</a>.</span>
+  </div>
+</fieldset>
+
+<fieldset id="fldset-files">
+  <legend>Data File(s)</legend>
+
+  <fieldset id="fldset-descriptions-file">
+    <div class="form-group">
+      <div class="form-check">
+        <input id="chk-phenotype-descriptions-transposed"
+               name="phenotype-descriptions-transposed"
+               type="checkbox"
+               class="form-check-input"
+               style="border: solid #8EABF0" />
+        <label for="chk-phenotype-descriptions-transposed"
+               class="form-check-label">
+          Description file transposed?</label>
+      </div>
+
+      <div class="non-resumable-elements">
+        <label for="finput-phenotype-descriptions" class="form-label">
+          Phenotype Descriptions</label>
+        <input id="finput-phenotype-descriptions"
+               name="phenotype-descriptions"
+               class="form-control"
+               type="file"
+               data-preview-table="tbl-preview-pheno-desc"
+               required="required"  />
+        <span class="form-text text-muted">
+          Provide a file that contains only the phenotype descriptions,
+          <a href="#docs-file-phenotype-description"
+             title="Documentation of the phenotype data file format.">
+            the documentation for the expected format of the file</a>.</span>
+      </div>
+      {{display_resumable_elements(
+      "resumable-phenotype-descriptions",
+      "phenotype descriptions",
+      '<p>Drag and drop the CSV file that contains the descriptions of your
+        phenotypes here.</p>
+
+      <p>The CSV file should be a matrix of
+        <strong>phenotypes × descriptions</strong> i.e. The first column
+        contains the phenotype names/identifiers whereas the first row is a list
+        of metadata fields like, "description", "units", etc.</p>
+
+      <p>If the format is transposed (i.e.
+        <strong>descriptions × phenotypes</strong>) select the checkbox above.
+      </p>
+
+      <p>Please see the
+        <a href="#docs-file-phenotype-description"
+           title="Documentation of the phenotype data file format.">
+          "Phenotypes Descriptions" documentation</a> section below for more
+        information on the expected format of the file provided here.</p>')}}
+      {{display_preview_table(
+      "tbl-preview-pheno-desc", "phenotype descriptions")}}
+    </div>
+  </fieldset>
+
+
+  <fieldset id="fldset-data-file">
+    <div class="form-group">
+      <div class="form-check">
+        <input id="chk-phenotype-data-transposed"
+               name="phenotype-data-transposed"
+               type="checkbox"
+               class="form-check-input"
+               style="border: solid #8EABF0" />
+        <label for="chk-phenotype-data-transposed" class="form-check-label">
+          Data file transposed?</label>
+      </div>
+
+      <div class="non-resumable-elements">
+        <label for="finput-phenotype-data" class="form-label">Phenotype Data</label>
+        <input id="finput-phenotype-data"
+               name="phenotype-data"
+               class="form-control"
+               type="file"
+               data-preview-table="tbl-preview-pheno-data"
+               required="required"  />
+        <span class="form-text text-muted">
+          Provide a file that contains only the phenotype data. See
+          <a href="#docs-file-phenotype-data"
+             title="Documentation of the phenotype data file format.">
+            the documentation for the expected format of the file</a>.</span>
+      </div>
+
+      {{display_resumable_elements(
+      "resumable-phenotype-data",
+      "phenotype data",
+      '<p>Drag and drop a CSV file that contains the phenotypes numerical data
+        here. You can click the "Browse" button (below and to the right) to
+        select the file from your computer.</p>
+
+      <p>The CSV should be a matrix of <strong>samples × phenotypes</strong>,
+        i.e. The first column contains the samples identifiers while the first
+        row is the list of phenotypes identifiers occurring in the phenotypes
+        descriptions file.</p>
+
+      <p>If the format is transposed (i.e <strong>phenotypes × samples</strong>)
+        select the checkbox above.</p>
+      <p>Please see the
+        <a href="#docs-file-phenotype-data"
+           title="Documentation of the phenotype data file format.">
+          "Phenotypes Data" documentation</a> section below for more information
+        on the expected format for the file provided here.</p>')}}
+      {{display_preview_table("tbl-preview-pheno-data", "phenotype data")}}
+    </div>
+  </fieldset>
+
+  
+  {%if population.Family in families_with_se_and_n%}
+  <fieldset id="fldset-se-file">
+    <div class="form-group">
+      <div class="form-check">
+        <input id="chk-phenotype-se-transposed"
+               name="phenotype-se-transposed"
+               type="checkbox"
+               class="form-check-input"
+               style="border: solid #8EABF0" />
+        <label for="chk-phenotype-se-transposed" class="form-check-label">
+          Standard-Errors file transposed?</label>
+      </div>
+      <div class="group non-resumable-elements">
+        <label for="finput-phenotype-se" class="form-label">Phenotype: Standard Errors</label>
+        <input id="finput-phenotype-se"
+               name="phenotype-se"
+               class="form-control"
+               type="file"
+               data-preview-table="tbl-preview-pheno-se"
+               required="required"  />
+        <span class="form-text text-muted">
+          Provide a file that contains only the standard errors for the phenotypes,
+          computed from the data above.</span>
+      </div>
+
+      {{display_resumable_elements(
+      "resumable-phenotype-se",
+      "standard errors",
+      '<p>Drag and drop a CSV file that contains the phenotypes standard-errors
+        data here. You can click the "Browse" button (below and to the right) to
+        select the file from your computer.</p>
+
+      <p>The CSV should be a matrix of <strong>samples × phenotypes</strong>,
+        i.e. The first column contains the samples identifiers while the first
+        row is the list of phenotypes identifiers occurring in the phenotypes
+        descriptions file.</p>
+
+      <p>If the format is transposed (i.e <strong>phenotypes × samples</strong>)
+        select the checkbox above.</p>
+
+      <p>Please see the
+        <a href="#docs-file-phenotype-se"
+           title="Documentation of the phenotype data file format.">
+          "Phenotypes Data" documentation</a> section below for more information
+        on the expected format of the file provided here.</p>')}}
+
+      {{display_preview_table("tbl-preview-pheno-se", "standard errors")}}
+    </div>
+  </fieldset>
+
+
+  <fieldset id="fldset-n-file">
+    <div class="form-group">
+      <div class="form-check">
+        <input id="chk-phenotype-n-transposed"
+               name="phenotype-n-transposed"
+               type="checkbox"
+               class="form-check-input"
+               style="border: solid #8EABF0" />
+        <label for="chk-phenotype-n-transposed" class="form-check-label">
+          Counts file transposed?</label>
+      </div>
+      <div class="non-resumable-elements">
+        <label for="finput-phenotype-n" class="form-label">Phenotype: Number of Samples/Individuals</label>
+        <input id="finput-phenotype-n"
+               name="phenotype-n"
+               class="form-control"
+               type="file"
+               data-preview-table="tbl-preview-pheno-n"
+               required="required"  />
+        <span class="form-text text-muted">
+          Provide a file that contains only the number of samples/individuals used in
+          the computation of the standard errors above.</span>
+      </div>
+
+      {{display_resumable_elements(
+      "resumable-phenotype-n",
+      "number of samples/individuals",
+      '<p>Drag and drop a CSV file that contains the samples\' phenotypes counts
+        data here. You can click the "Browse" button (below and to the right) to
+        select the file from your computer.</p>
+
+      <p>The CSV should be a matrix of <strong>samples × phenotypes</strong>,
+        i.e. The first column contains the samples identifiers while the first
+        row is the list of phenotypes identifiers occurring in the phenotypes
+        descriptions file.</p>
+
+      <p>If the format is transposed (i.e <strong>phenotypes × samples</strong>)
+        select the checkbox above.</p>
+
+      <p>Please see the
+        <a href="#docs-file-phenotype-se"
+           title="Documentation of the phenotype data file format.">
+          "Phenotypes Data" documentation</a> section below for more information
+        on the expected format of the file provided here.</p>')}}
+
+      {{display_preview_table("tbl-preview-pheno-n", "number of samples/individuals")}}
+    </div>
+  </fieldset>
+</fieldset>
+{%endif%}
+{%endblock%}
+
+
+{%block page_documentation%}
+<div class="row">
+  <h2 class="heading" id="docs-help">Help</h2>
+  <h3 class="subheading">Common Features</h3>
+  <p>The following are the common expectations for <strong>ALL</strong> the
+    files provided in the form above:
+    <ul>
+      <li>The file <strong>MUST</strong> be character-separated values (CSV)
+        text file</li>
+      <li>The first row in the file <strong>MUST</strong> be a heading row, and
+        will be composed of the list identifiers for all of
+        samples/individuals/cases involved in your study.</li>
+      <li>The first column of data in the file <strong>MUST</strong> be the
+        identifiers for all of the phenotypes you wish to upload.</li>
+    </ul>
+  </p>
+
+  <p>If you do not specify the separator character, then we will assume a
+    <strong>TAB</strong> character was used as your separator.</p>
+
+  <p>We also assume you might include comments lines in your files. In that
+    case, if you do not specify what character denotes that a line in your files
+    is a comment line, we will assume the <strong>#</strong> character.<br />
+    A comment <strong>MUST ALWAYS</strong> begin at the start of the line marked
+    with the comment character specified.</p>
+
+  <h3 class="subheading" id="docs-file-metadata">File Metadata</h3>
+  <p>We request some details about your files to help us parse and process the
+    files correctly. The details we collect are:</p>
+  <dl>
+    <dt id="docs-file-separator">File separator</dt>
+    <dd>The files you provide should be character-separated value (CSV) files.
+      We need to know what character you used to separate the values in your
+      file. Some common ones are the Tab character, the comma, etc.<br />
+      Providing that information makes it possible for the system to parse and
+      process your files correctly.<br>
+      <strong>NOTE:</strong> All the files you upload MUST use the same
+      separator.</dd>
+
+    <dt id="docs-file-comment-character">Comment character</dt>
+    <dd>We support use of comment lines in your files. We only support one type
+      of comment style, the <em>line comment</em>.<br />
+      This mean the comment begins at the start of the line, and the end of that
+      line indicates the end of that comment. If you have a really long comment,
+      then you need to break it across multiple lines, marking each line a
+      comment line.<br />
+      The "comment character" is the character at the start of the line that
+      indicates that the line is a line comment.</dd>
+
+    <dt id="docs-file-na">No-Value indicator(s)</dt>
+    <dd>Data in the real world is messy, and in some cases, entirely absent. You
+      need to indicate, in your files, that a particular field did not have a
+      value, and once you do that, you then need to let the system know how you
+      mark such fields. Common ways of indicating "empty values" are, leaving
+      the field blank, using a character such as '-', or using strings like
+      "NA", "N/A", "NULL", etc.<br />
+      Providing this information will help with parsing and processing such
+      no-value fields the correct way.</dd>
+  </dl>
+
+  <h3 class="subheading" id="docs-file-phenotype-description">
+    file: Phenotypes Descriptions</h3>
+  <p>The data in this file is a matrix of <em>phenotypes × metadata-fields</em>.
+    Please note we use the term "metadata-fields" above loosely, due to lack of
+    a good word for this.</p>
+  <p>The file <strong>MUST</strong> have columns in this order:
+    <dl>
+      <dt>Phenotype Identifiers</dt>
+      <dd>These are the names/identifiers for your phenotypes. These
+        names/identifiers are the same ones you will have in all the other files you are
+        uploading.</dd>
+
+      <dt>Descriptions</dt>
+      <dd>Each phenotype will need a description. Good description are necessary
+        to inform other people of what the data is about. Good description are
+        hard to construct, so we provide
+        <a href="https://info.genenetwork.org/faq.php#q-22"
+           title="How to write phenotype descriptions">
+          advice on describing your phenotypes.</a></dd>
+
+      <dt>Units</dt>
+      <dd>Each phenotype will need units for the measurements taken. If there are
+        none, then indicate the field is a no-value field.</dd>
+  </dl></p>
+  <p>You can add more columns after those three if you want to, but these 3
+    <strong>MUST</strong> be present.</p>
+  <p>The file would, for example, look like the following:</p>
+  <code>id,description,units,…<br />
+    pheno10001|Central nervous system, behavior, cognition; …|mg|…<br />
+    pheno10002|Aging, metabolism, central nervous system: …|mg|…<br />
+    â‹®<br /></code>
+
+  <p><strong>Note 01</strong>: The first usable row is the heading row.</p>
+  <p><strong>Note 02: </strong>This example demonstrates a subtle issue that
+    could make your CSV file invalid &mdash; the choice of your field separator
+    character.<br >
+    In the example above, we use the pipe character (<code>|</code>) as our
+    field separator. This is because, if we follow the advice on how to write
+    good descriptions, then we cannot use the comma as our separator &ndash; if
+    we did, then our CSV file would be invalid because the system would have no
+    way to tell the difference between the comma as a field separator, and the
+    comma as a way to separate the "general category and ontology terms".</p>
+
+  <h3 class="subheading">file: Phenotype Data, Standard Errors and/or Sample Counts</h3>
+  <span id="docs-file-phenotype-data"></span>
+  <span id="docs-file-phenotype-se"></span>
+  <span id="docs-file-phenotype-n"></span>
+  <p>The data is a matrix of <em>samples(or individuals) × phenotypes</em>, e.g.</p>
+  <code>
+    # num-cases: 2549
+    # num-phenos: 13
+    id,pheno10001,pheno10002,pheno10003,pheno10004,53.099998,…<br />
+    IND001,61.400002,49,62.5,55.099998,…<br />
+    IND002,54.099998,50.099998,53.299999,55.099998,…<br />
+    IND003,483,403,501,403,…<br />
+    IND004,49.799999,45.5,62.900002,NA,…<br />
+    â‹®<br /></code>
+
+  <p>where <code>IND001,IND002,IND003,IND004,…</code> are the
+    samples/individuals/cases in your study, and
+    <code>pheno10001,pheno10002,pheno10004,pheno10004,…</code> are the
+    identifiers for your phenotypes.</p>
+  <p>The lines beginning with the "<em>#</em>" symbol (i.e.
+    <code># num-cases: 2549</code> and <code># num-phenos: 13</code> are comment
+    lines and will be ignored</p>
+  <p>In this example, the comma (,) is used as the file separator.</p>
+</div>
+
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_pheno_dataset_card(species, population, dataset)}}
+{%endblock%}
+
+
+{%block more_javascript%}
+<script src="{{url_for('base.node_modules',
+             filename='resumablejs/resumable.js')}}"></script>
+<script type="text/javascript" src="/static/js/files.js"></script>
+
+<script type="text/javascript">
+  $("#btn-reset-file-separator").on("click", (event) => {
+      event.preventDefault();
+      $("#txt-file-separator").val("\t");
+      $("#txt-file-separator").trigger("change");
+  });
+  $("#btn-reset-file-comment-character").on("click", (event) => {
+      event.preventDefault();
+      $("#txt-file-comment-character").val("#");
+      $("#txt-file-comment-character").trigger("change");
+  });
+  $("#btn-reset-file-na").on("click", (event) => {
+      event.preventDefault();
+      $("#txt-file-na").val("- NA N/A");
+      $("#txt-file-na").trigger("change");
+  });
+
+  var update_preview = (table, filedata, formdata, numrows) => {
+      table.find("thead tr").remove()
+      table.find(".data-row").remove();
+      var linenum = 0;
+      var tableheader = table.find("thead");
+      var tablebody = table.find("tbody");
+      var numheadings = 0;
+      var navalues = formdata
+          .na_strings
+          .split(" ")
+          .map((v) => {return v.trim();})
+          .filter((v) => {return Boolean(v);});
+      filedata.forEach((line) => {
+          if(line.startsWith(formdata.comment_char) || linenum >= numrows) {
+              return false;
+          }
+          var row = $("<tr></tr>");
+          line.split(formdata.separator)
+              .map((field) => {
+                  var value = field.trim();
+                  if(navalues.includes(value)) {
+                      return "⋘NUL⋙";
+                  }
+                  return value;
+              })
+              .filter((field) => {
+                  return (field !== "" && field != undefined && field != null);
+              })
+              .forEach((field) => {
+                  if(linenum == 0) {
+                      numheadings += 1;
+                      var tablefield = $("<th></th>");
+                      tablefield.text(field);
+                      row.append(tablefield);
+                  } else {
+                      add_class(row, "data-row");
+                      var tablefield = $("<td></td>");
+                      tablefield.text(field);
+                      row.append(tablefield);
+                  }
+              });
+
+          if(linenum == 0) {
+              tableheader.append(row);
+          } else {
+              tablebody.append(row);
+          }
+          linenum += 1;
+      });
+
+      if(table.find("tbody tr.data-row").length > 0) {
+          add_class(table.find(".data-row-template"), "visually-hidden");
+      } else {
+          remove_class(table.find(".data-row-template"), "visually-hidden");
+      }
+  };
+
+  var makePreviewUpdater = (preview_table) => {
+      return (data) => {
+          update_preview(
+              preview_table,
+              data,
+              filesMetadata(),
+              PREVIEW_ROWS);
+      };
+  };
+
+  var preview_tables_to_elements_map = {
+      "#tbl-preview-pheno-desc": "#finput-phenotype-descriptions",
+      "#tbl-preview-pheno-data": "#finput-phenotype-data",
+      "#tbl-preview-pheno-se": "#finput-phenotype-se",
+      "#tbl-preview-pheno-n": "#finput-phenotype-n"
+  };
+
+  var filesMetadata = () => {
+      return {
+          "separator": $("#txt-file-separator").val(),
+          "comment_char": $(
+              "#txt-file-comment-character").val(),
+          "na_strings": $("#txt-file-na").val()
+      }
+  };
+
+  var PREVIEW_ROWS = 5;
+
+  var handler_update_previews = (event) => {
+      Object.entries(preview_tables_to_elements_map).forEach((mapentry) => {
+          var preview_table = $(mapentry[0]);
+          var file_input = $(mapentry[1]);
+          if(file_input[0].files.length > 0) {
+              readFirstNLines(
+                  file_input[0].files[0],
+                  10,
+                  [makePreviewUpdater(preview_table)]);
+          }
+      });
+
+      if(typeof(resumables) !== "undefined") {
+          resumables.forEach((resumable) => {
+              if(resumable.files.length > 0) {
+                  readFirstNLines(
+                      resumable.files[0].file,
+                      10,
+                      [makePreviewUpdater(resumable.preview_table)]);
+              }
+          });
+      }
+  };
+
+  [
+      "#txt-file-separator",
+      "#txt-file-comment-character",
+      "#txt-file-na"
+  ].forEach((elementid) => {
+      $(elementid).on("change", handler_update_previews);
+  });
+
+  [
+      "#finput-phenotype-descriptions",
+      "#finput-phenotype-data",
+      "#finput-phenotype-se",
+      "#finput-phenotype-n"
+  ].forEach((elementid) => {
+      $(elementid).on("change", (event) => {
+          readFirstNLines(
+              event.target.files[0],
+              10,
+              [makePreviewUpdater(
+                  $("#" + event.target.getAttribute("data-preview-table")))]);
+      });
+  });
+
+
+  var resumableDisplayFiles = (display_area, files) => {
+      files.forEach((file) => {
+          display_area.find(".file-display").remove();
+          var display_element = display_area
+              .find(".file-display-template")
+              .clone();
+          remove_class(display_element, "visually-hidden");
+          remove_class(display_element, "file-display-template");
+          add_class(display_element, "file-display");
+          display_element.find(".filename").text(file.name
+                                                || file.fileName
+                                                || file.relativePath
+                                                || file.webkitRelativePath);
+          display_element.find(".filesize").text(
+              (file.size / (1024*1024)).toFixed(2) + "MB");
+          display_element.find(".fileuniqueid").text(file.uniqueIdentifier);
+          display_element.find(".filemimetype").text(file.file.type);
+          display_area.append(display_element);
+      });
+  };
+
+
+  var indicateProgress = (resumable, progress_bar) => {
+      return () => {/*Has no event!*/
+          var progress = (resumable.progress() * 100).toFixed(2);
+          var pbar = progress_bar.find(".progress-bar");
+          remove_class(progress_bar, "visually-hidden");
+          pbar.css("width", progress+"%");
+          pbar.attr("aria-valuenow", progress);
+          pbar.text("Uploading: " + progress + "%");
+      };
+  };
+
+  var retryUpload = (retry_button, cancel_button) => {
+      retry_button.on("click", (event) => {
+          resumable.files.forEach((file) => {file.retry();});
+          add_class(retry_button, "visually-hidden");
+          remove_class(cancel_button, "visually-hidden");
+          add_class(browse_button, "visually-hidden");
+      });
+  };
+
+  var cancelUpload = (cancel_button, retry_button) => {
+      cancel_button.on("click", (event) => {
+          resumable.files.forEach((file) => {
+              if(file.isUploading()) {
+                  file.abort();
+              }
+          });
+          add_class(cancel_button, "visually-hidden");
+          remove_class(retry_button, "visually-hidden");
+          remove_class(browse_button, "visually-hidden");
+      });
+  };
+
+
+  var startUpload = (browse_button, retry_button, cancel_button) => {
+      return (event) => {
+          remove_class(cancel_button, "visually-hidden");
+          add_class(retry_button, "visually-hidden");
+          add_class(browse_button, "visually-hidden");
+      };
+  };
+
+  var processForm = (form) => {
+      var formdata = new FormData(form);
+      uploaded_files.forEach((msg) => {
+          formdata.delete(msg["file-input-name"]);
+          formdata.append(msg["file-input-name"], JSON.stringify({
+              "uploaded-file": msg["uploaded-file"],
+              "original-name": msg["original-name"]
+          }));
+      });
+      formdata.append("resumable-upload", "true");
+      formdata.append("publication-id", $("#txt-publication-id").val());
+      return formdata;
+  }
+
+  var uploaded_files = new Set();
+  var submitForm = (new_file) => {
+      uploaded_files.add(new_file);
+      if(uploaded_files.size === resumables.length) {
+          var form = $("#frm-add-phenotypes");
+          if(form.length !== 1) {
+              // TODO: Handle error somehow?
+              alert("Could not find form!!!");
+              return false;
+          }
+
+          $.ajax({
+              "url": form.attr("action"),
+              "type": "POST",
+              "data": processForm(form[0]),
+              "processData": false,
+              "contentType": false,
+              "success": (data, textstatus, jqxhr) => {
+                  // TODO: Redirect to endpoint that should come as part of the
+                  //       success/error message.
+                  console.log("SUCCESS DATA: ", data);
+                  console.log("SUCCESS STATUS: ", textstatus);
+                  console.log("SUCCESS jqXHR: ", jqxhr);
+                  window.location.assign(window.location.origin + data["redirect-to"]);
+              },
+          });
+          return false;
+      }
+      return false;
+  };
+
+  var uploadSuccess = (file_input_name) => {
+      return (file, message) => {
+          submitForm({...JSON.parse(message), "file-input-name": file_input_name});
+      };
+  };
+
+
+  var uploadError = () => {
+      return (message, file) => {
+          $("#frm-add-phenotypes input[type=submit]").removeAttr("disabled");
+          console.log("THE FILE:", file);
+          console.log("THE ERROR MESSAGE:", message);
+      };
+  };
+
+
+
+  var makeResumableObject = (form_id, file_input_id, resumable_element_id, preview_table_id) => {
+      var the_form = $("#" + form_id);
+      var file_input = $("#" + file_input_id);
+      var submit_button = the_form.find("input[type=submit]");
+      if(file_input.length != 1) {
+          return false;
+      }
+      var r = errorHandler(
+          fileSuccessHandler(
+              uploadStartHandler(
+                  filesAddedHandler(
+                      markResumableDragAndDropElement(
+                          makeResumableElement(
+                              the_form.attr("data-resumable-target"),
+                              file_input.parent(),
+                              $("#" + resumable_element_id),
+                              submit_button,
+                              ["csv", "tsv", "txt"]),
+                          file_input.parent(),
+                          $("#" + resumable_element_id),
+                          $("#" + resumable_element_id + "-browse-button")),
+                      (files) => {
+                          // TODO: Also trigger preview!
+                          resumableDisplayFiles(
+                              $("#" + resumable_element_id + "-selected-files"), files);
+                          files.forEach((file) => {
+                              readFirstNLines(
+                                  file.file,
+                                  10,
+                                  [makePreviewUpdater(
+                                      $("#" + preview_table_id))])
+                          });
+                      }),
+                  startUpload($("#" + resumable_element_id + "-browse-button"),
+                              $("#" + resumable_element_id + "-retry-button"),
+                              $("#" + resumable_element_id + "-cancel-button"))),
+              uploadSuccess(file_input.attr("name"))),
+          uploadError());
+
+      /** Setup progress indicator **/
+      progressHandler(
+          r,
+          indicateProgress(r, $("#" + resumable_element_id + "-progress-bar")));
+
+      return r;
+  };
+
+  var resumables = [
+      ["frm-add-phenotypes", "finput-phenotype-descriptions", "resumable-phenotype-descriptions", "tbl-preview-pheno-desc"],
+      ["frm-add-phenotypes", "finput-phenotype-data", "resumable-phenotype-data", "tbl-preview-pheno-data"],
+      ["frm-add-phenotypes", "finput-phenotype-se", "resumable-phenotype-se", "tbl-preview-pheno-se"],
+      ["frm-add-phenotypes", "finput-phenotype-n", "resumable-phenotype-n", "tbl-preview-pheno-n"],
+  ].map((row) => {
+      r = makeResumableObject(row[0], row[1], row[2], row[3]);
+      r.preview_table = $("#" + row[3]);
+      return r;
+  }).filter((val) => {
+      return Boolean(val);
+  });
+
+  $("#frm-add-phenotypes input[type=submit]").on("click", (event) => {
+      event.preventDefault();
+      console.debug();
+      if ($("#txt-publication-id").val() == "") {
+          alert("You MUST provide a publication for the phenotypes.");
+          return false;
+      }
+      // TODO: Check all the relevant files exist
+      // TODO: Verify that files are not duplicated
+      var filenames = [];
+      var nondupfiles = [];
+      resumables.forEach((r) => {
+          var fname = r.files[0].file.name;
+          filenames.push(fname);
+          if(!nondupfiles.includes(fname)) {
+              nondupfiles.push(fname);
+          }
+      });
+
+      // Check that all files were provided
+      if(resumables.length !== filenames.length) {
+          window.alert("You MUST provide all the files requested.");
+          event.target.removeAttribute("disabled");
+          return false;
+      }
+
+      // Check that there are no duplicate files
+      var duplicates = Object.entries(filenames.reduce(
+          (acc, curr, idx, arr) => {
+              acc[curr] = (acc[curr] || 0) + 1;
+              return acc;
+          },
+          {})).filter((entry) => {return entry[1] !== 1;});
+      if(duplicates.length > 0) {
+          var msg = "The file(s):\r\n";
+          msg = msg + duplicates.reduce(
+              (msgstr, afile) => {
+                  return msgstr + "  • " + afile[0] + "\r\n";
+              },
+              "");
+          msg = msg + "is(are) duplicated. Please fix and try again.";
+          window.alert(msg);
+          event.target.removeAttribute("disabled");
+          return false;
+      }
+      // TODO: Check all fields
+      // Start the uploads.
+      event.target.setAttribute("disabled", "disabled");
+      resumables.forEach((r) => {r.upload();});
+  });
+</script>
+{%endblock%}
diff --git a/uploader/templates/phenotypes/add-phenotypes-with-rqtl2-bundle.html b/uploader/templates/phenotypes/add-phenotypes-with-rqtl2-bundle.html
new file mode 100644
index 0000000..898fc0c
--- /dev/null
+++ b/uploader/templates/phenotypes/add-phenotypes-with-rqtl2-bundle.html
@@ -0,0 +1,207 @@
+{%extends "phenotypes/add-phenotypes-base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "phenotypes/macro-display-pheno-dataset-card.html" import display_pheno_dataset_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="add-phenotypes"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">Add Phenotypes</a>
+</li>
+{%endblock%}
+
+{%block frm_add_phenotypes_documentation%}
+<p>Select the zip file bundle containing information on the phenotypes you
+  wish to upload, then click the "Upload Phenotypes" button below to
+  upload the data.</p>
+<p>If you wish to upload the files individually instead,
+  <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}"
+     title="">click here</a>.</p>
+<p>See the <a href="#section-file-formats">File Formats</a> section below
+  to get an understanding of what is expected of the bundle files you
+  upload.</p>
+{%endblock%}
+
+{%block frm_add_phenotypes_elements%}
+<div class="form-group">
+  <label for="finput-phenotypes-bundle" class="form-label">
+    Phenotypes Bundle</label>
+  <input type="file"
+         id="finput-phenotypes-bundle"
+         name="phenotypes-bundle"
+         accept="application/zip, .zip"
+	 required="required"
+         class="form-control" />
+</div>
+{%endblock%}
+
+{%block page_documentation%}
+<div class="row">
+  <h2 class="heading" id="section-file-formats">File Formats</h2>
+  <p>We accept an extended form of the
+    <a href="https://kbroman.org/qtl2/assets/vignettes/input_files.html#format-of-the-data-files"
+       title="R/qtl2 software input file format documentation">
+      input files' format used with the R/qtl2 software</a> as a single ZIP
+    file</p>
+  <p>The files that are used for this feature are:
+    <ul>
+      <li>the <em>control</em> file</li>
+      <li><em>pheno</em> file(s)</li>
+      <li><em>phenocovar</em> file(s)</li>
+      <li><em>phenose</em> files(s)</li>
+    </ul>
+  </p>
+  <p>Other files within the bundle will be ignored, for this feature.</p>
+  <p>The following section will detail the expectations for each of the
+    different file types within the uploaded ZIP file bundle for phenotypes:</p>
+
+  <h3 class="subheading">Control File</h3>
+  <p>There <strong>MUST be <em>one, and only one</em></strong> file that acts
+    as the control file. This file can be:
+    <ul>
+      <li>a <em>JSON</em> file, or</li>
+      <li>a <em>YAML</em> file.</li>
+    </ul>
+  </p>
+
+  <p>The control file is useful for defining things about the bundle such as:</p>
+  <ul>
+    <li>The field separator value (default: <code>sep: ','</code>). There can
+      only ever be one field separator and it <strong>MUST</strong> be the same
+      one for <strong>ALL</strong> files in the bundle.</li>
+    <li>The comment character (default: <code>comment.char: '#'</code>). Any
+      line that starts with this character will be considered a comment line and
+      be ignored in its entirety.</li>
+    <li>Code for missing values (default: <code>na.strings: 'NA'</code>). You
+      can specify more than one code to indicate missing values, e.g.
+      <code>{…, "na.strings": ["NA", "N/A", "-"], …}</code></li>
+  </ul>
+
+  <h3 class="subheading"><em>pheno</em> File(s)</h3>
+  <p>These files are the main data files. You must have at least one of these
+    files in your bundle for it to be valid for this step.</p>
+  <p>The data is a matrix of <em>individuals × phenotypes</em> by default, as
+    below:<br />
+    <code>
+      id,10001,10002,10003,10004,…<br />
+      BXD1,61.400002,54.099998,483,49.799999,…<br />
+      BXD2,49,50.099998,403,45.5,…<br />
+      BXD5,62.5,53.299999,501,62.900002,…<br />
+      BXD6,53.099998,55.099998,403,NA,…<br />
+      â‹®<br /></code>
+  </p>
+  <p>If the <code>pheno_transposed</code> value is set to <code>True</code>,
+    then the data will be a <em>phenotypes × individuals</em> matrix as in the
+    example below:<br />
+    <code>
+      id,BXD1,BXD2,BXD5,BXD6,…<br />
+      10001,61.400002,49,62.5,53.099998,…<br />
+      10002,54.099998,50.099998,53.299999,55.099998,…<br />
+      10003,483,403,501,403,…<br />
+      10004,49.799999,45.5,62.900002,NA,…<br />
+      â‹®
+    </code>
+  </p>
+
+
+  <h3 class="subheading"><em>phenocovar</em> File(s)</h3>
+  <p>At least one phenotypes metadata file with the metadata values such as
+    descriptions, PubMed Identifier, publication titles (if present), etc.</p>
+  <p>The data in this/these file(s) is a matrix of
+    <em>phenotypes × phenotypes-covariates</em>. The first column is always the
+    phenotype names/identifiers — same as in the R/qtl2 format.</p>
+  <p><em>phenocovar</em> files <strong>should never be transposed</strong>!</p>
+  <p>This file <strong>MUST</strong> be present in the bundle, and have data for
+    the bundle to be considered valid by our system for this step.<br />
+    In addition to that, the following are the fields that <strong>must be
+      present</strong>, and
+    have values, in the file before the file is considered valid:
+    <ul>
+      <li><em>description</em>: A description for each phenotype. Useful
+        for users to know what the phenotype is about.</li>
+      <li><em>units</em>: The units of measurement for the phenotype,
+        e.g. milligrams for brain weight, centimetres/millimetres for
+        tail-length, etc.</li>
+  </ul></p>
+
+  <p>The following <em>optional</em> fields can also be provided:
+    <ul>
+      <li><em>pubmedid</em>: A PubMed Identifier for the publication where
+        the phenotype is published. If this field is not provided, the system will
+        assume your phenotype is not published.</li>
+    </ul>
+  </p>
+  <p>These files will be marked up in the control file with the
+    <code>phenocovar</code> key, as in the examples below:
+    <ol>
+      <li>JSON: single file<br />
+        <code>{<br />
+          &nbsp;&nbsp;â‹®,<br />
+          &nbsp;&nbsp;"phenocovar": "your_covariates_file.csv",<br />
+          &nbsp;&nbsp;â‹®<br />
+          }
+        </code>
+      </li>
+      <li>JSON: multiple files<br />
+        <code>{<br />
+          &nbsp;&nbsp;â‹®,<br />
+          &nbsp;&nbsp;"phenocovar": [<br />
+          &nbsp;&nbsp;&nbsp;&nbsp;"covariates_file_01.csv",<br />
+          &nbsp;&nbsp;&nbsp;&nbsp;"covariates_file_01.csv",<br />
+          &nbsp;&nbsp;&nbsp;&nbsp;â‹®<br />
+          &nbsp;&nbsp;],<br />
+          &nbsp;&nbsp;â‹®<br />
+          }
+        </code>
+      </li>
+      <li>YAML: single file or<br />
+        <code>
+          â‹®<br />
+          phenocovar: your_covariates_file.csv<br />
+          â‹®
+        </code>
+      </li>
+      <li>YAML: multiple files<br />
+        <code>
+          â‹®<br />
+          phenocovar:<br />
+          - covariates_file_01.csv<br />
+          - covariates_file_02.csv<br />
+          - covariates_file_03.csv<br />
+          …<br />
+          â‹®
+        </code>
+      </li>
+    </ol>
+  </p>
+
+  <h3 class="subheading"><em>phenose</em> and <em>phenonum</em> File(s)</h3>
+  <p>These are extensions to the R/qtl2 standard, i.e. these types ofs file are
+    not supported by the original R/qtl2 file format</p>
+  <p>We use these files to upload the standard errors (<em>phenose</em>) when
+    the data file (<em>pheno</em>) is average data. In that case, the
+    <em>phenonum</em> file(s) contains the number of individuals that were
+    involved when computing the averages.</p>
+  <p>Both types of files are matrices of <em>individuals × phenotypes</em> by
+    default. Like the related <em>pheno</em> files, if
+    <code>pheno_transposed: True</code>, then the file will be a matrix of
+    <em>phenotypes × individuals</em>.</p>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_pheno_dataset_card(species, population, dataset)}}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/base.html b/uploader/templates/phenotypes/base.html
new file mode 100644
index 0000000..adbc012
--- /dev/null
+++ b/uploader/templates/phenotypes/base.html
@@ -0,0 +1,19 @@
+{%extends "populations/base.html"%}
+
+{%block lvl3_breadcrumbs%}
+<li {%if activelink=="phenotypes"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  {%if dataset is mapping%}
+  <a href="{{url_for('species.populations.phenotypes.view_dataset',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">{{dataset.Name}}</a>
+  {%else%}
+  <a href="{{url_for('species.populations.phenotypes.index')}}">Phenotypes</a>
+  {%endif%}
+</li>
+{%block lvl4_breadcrumbs%}{%endblock%}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/bulk-edit-upload.html b/uploader/templates/phenotypes/bulk-edit-upload.html
new file mode 100644
index 0000000..d0f38f5
--- /dev/null
+++ b/uploader/templates/phenotypes/bulk-edit-upload.html
@@ -0,0 +1,62 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="view-dataset"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.view_dataset',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">View</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+<div class="row">
+  <p>Upload the edited file you downloaded and edited.</p>
+</div>
+
+<div class="row">
+  <form id="frm-bulk-edit-upload"
+        class="form-horizontal"
+        method="POST"
+        action="{{url_for(
+                'species.populations.phenotypes.edit_upload_phenotype_data',
+                species_id=species.SpeciesId,
+                population_id=population.Id,
+                dataset_id=dataset.Id)}}"
+        enctype="multipart/form-data">
+
+    <div class="form-group row">
+      <label for="file-upload-bulk-edit-upload"
+             class="form-label col-form-label col-sm-2">
+        Edited File</label>
+      <div class="col-sm-10">
+        <input id="file-upload-bulk-edit-upload"
+               name="file-upload-bulk-edit-upload"
+               class="form-control"
+               type="file"
+               accept="text/tab-separated-values"
+               required="required" />
+      </div>
+    </div>
+
+    <input type="submit" class="btn btn-primary"
+           value="upload to edit" />
+
+  </form>
+</div>
+{%endblock%}
+
+
+{%block javascript%}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/create-dataset.html b/uploader/templates/phenotypes/create-dataset.html
new file mode 100644
index 0000000..19a2b34
--- /dev/null
+++ b/uploader/templates/phenotypes/create-dataset.html
@@ -0,0 +1,108 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="create-dataset"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.create_dataset',
+           species_id=species.SpeciesId,
+           population_id=population.Id)}}">Create Datasets</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <p>Create a new phenotype dataset.</p>
+</div>
+
+<div class="row">
+  <form id="frm-create-pheno-dataset"
+        action="{{url_for('species.populations.phenotypes.create_dataset',
+                species_id=species.SpeciesId,
+                population_id=population.Id)}}"
+        method="POST">
+
+    <div class="form-group">
+      <label class="form-label" for="txt-dataset-name">Name</label>
+      {%if errors["dataset-name"] is defined%}
+      <small class="form-text text-muted danger">
+        <p>{{errors["dataset-name"]}}</p></small>
+      {%endif%}
+      <input type="text"
+             name="dataset-name"
+             id="txt-dataset-name"
+             value="{{original_formdata.get('dataset-name') or (population.Name + 'Publish')}}"
+             {%if errors["dataset-name"] is defined%}
+             class="form-control danger"
+             {%else%}
+             class="form-control"
+             {%endif%}
+             required="required" />
+      <small class="form-text text-muted">
+        <p>A short representative name for the dataset.</p>
+        <p>Recommended: Use the population name and append "Publish" at the end.
+          <br />This field will only accept names composed of
+          letters ('A-Za-z'), numbers (0-9), hyphens and underscores.</p>
+      </small>
+    </div>
+
+    <div class="form-group">
+      <label class="form-label" for="txt-dataset-fullname">Full Name</label>
+      {%if errors["dataset-fullname"] is defined%}
+      <small class="form-text text-muted danger">
+        <p>{{errors["dataset-fullname"]}}</p></small>
+      {%endif%}
+      <input id="txt-dataset-fullname"
+             name="dataset-fullname"
+             type="text"
+             value="{{original_formdata.get('dataset-fullname', '')}}"
+             {%if errors["dataset-fullname"] is defined%}
+             class="form-control danger"
+             {%else%}
+             class="form-control"
+             {%endif%}
+             required="required" />
+      <small class="form-text text-muted">
+        <p>A longer, descriptive name for the dataset. The name is meant for use
+          by humans, and therefore, it should be clear what the dataset contains
+          from the name.</p>
+      </small>
+    </div>
+
+    <div class="form-group">
+      <label class="form-label" for="txt-dataset-shortname">Short Name</label>
+      <input id="txt-dataset-shortname"
+             name="dataset-shortname"
+             type="text"
+             class="form-control"
+             value="{{original_formdata.get('dataset-shortname') or (population.Name + 'Publish')}}" />
+      <small class="form-text text-muted">
+        <p>An optional, short name for the dataset. <br />
+          If this is not provided, it will default to the value provided for the
+          <strong>Name</strong> field above.</p></small>
+    </div>
+
+    <div class="form-group">
+      <input type="submit"
+             class="btn btn-primary"
+             value="create phenotype dataset"  />
+    </div>
+
+  </form>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/edit-phenotype.html b/uploader/templates/phenotypes/edit-phenotype.html
new file mode 100644
index 0000000..115d6af
--- /dev/null
+++ b/uploader/templates/phenotypes/edit-phenotype.html
@@ -0,0 +1,208 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="edit-phenotype"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.edit_phenotype_data',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id,
+           xref_id=xref_id)}}">View Datasets</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <h2 class="heading">edit phenotype data</h2>
+  <p>The forms provided in this page help you update the data for the
+    phenotypes, and the publication information for the phenotype,
+    respectively.</p>
+</div>
+
+<div class="row">
+  <h3 class="subheading">Basic metadata</h3>
+  <form name="frm-phenotype-basic-metadata"
+        class="form-horizontal"
+        method="POST"
+        action="{{url_for(
+                'species.populations.phenotypes.edit_phenotype_data',
+                species_id=species.SpeciesId,
+                population_id=population.Id,
+                dataset_id=dataset.Id,
+                xref_id=xref_id)}}">
+    <input type="hidden" name="phenotype-id" value="{{phenotype.Id}}" />
+    <div class="form-group">
+      <label for="txt-pre-publication-description"
+             class="control-label col-sm-2">Pre-Publication Description</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-pre-publication-description"
+               name="pre-publication-description"
+               class="form-control"
+               value="{{phenotype['Pre_publication_description'] or ''}}" />
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-pre-publication-abbreviation"
+             class="control-label col-sm-2">Pre-Publication Abbreviation</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-pre-publication-abbreviation"
+               name="pre-publication-abbreviation"
+               class="form-control"
+               value="{{phenotype['Pre_publication_abbreviation'] or ''}}" />
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-post-publication-description"
+             class="control-label col-sm-2">Post-Publication Description</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-post-publication-description"
+               name="post-publication-description"
+               class="form-control"
+               value="{{phenotype['Post_publication_description'] or ''}}" />
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-post-publication-abbreviation"
+             class="control-label col-sm-2">Post-Publication Abbreviation</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-post-publication-abbreviation"
+               name="post-publication-abbreviation"
+               class="form-control"
+               value="{{phenotype['Post_publication_abbreviation'] or ''}}" />
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-original-description"
+             class="control-label col-sm-2">Original Description</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-original-description"
+               name="original-description"
+               class="form-control"
+               value="{{phenotype['Original_description'] or ''}}" />
+      </div>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-units"
+             class="control-label col-sm-2">units</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-units"
+               name="units"
+               class="form-control"
+               required="required"
+               value="{{phenotype['Units']}}" />
+      </div>
+    </div>
+
+    <div class="form-group">
+      <div class="col-sm-offset-2 col-sm-10">
+        <input type="submit"
+               name="submit"
+               class="btn btn-primary"
+               value="update basic metadata">
+      </div>
+    </div>
+  </form>
+</div>
+
+
+<div class="row">
+  <h3 class="subheading">phenotype data</h3>
+  <form id="frm-edit-phenotype-data"
+        class="form-horizontal"
+        method="POST"
+        action="{{url_for(
+                'species.populations.phenotypes.edit_phenotype_data',
+                species_id=species.SpeciesId,
+                population_id=population.Id,
+                dataset_id=dataset.Id,
+                xref_id=xref_id)}}">
+    <div style="max-height: 23.37em;overflow-y: scroll;">
+      <table class="table table-striped table-responsive table-form-table">
+        <thead style="position: sticky; top: 0;">
+          <tr>
+            <th>#</th>
+            <th>Sample</th>
+            <th>Value</th>
+            {%if population.Family in families_with_se_and_n%}
+            <th>Standard-Error</th>
+            <th>Number of Samples</th>
+            {%endif%}
+          </tr>
+        </thead>
+
+        <tbody>
+          {%for item in phenotype.data%}
+          <tr>
+            <td>{{loop.index}}</td>
+            <td>{{item.StrainName}}</td>
+            <td>
+              <input type="text"
+                     name="value-new::{{item.DataId}}::{{item.StrainId}}"
+                     value="{{item.value}}"
+                     class="form-control" />
+              <input type="hidden"
+                     name="value-original::{{item.DataId}}::{{item.StrainId}}"
+                     value="{{item.value}}" /></td>
+            {%if population.Family in families_with_se_and_n%}
+            <td>
+              <input type="text"
+                     name="se-new::{{item.DataId}}::{{item.StrainId}}"
+                     value="{{item.error or ''}}"
+                     data-original-value="{{item.error or ''}}"
+                     class="form-control" />
+              <input type="hidden"
+                     name="se-original::{{item.DataId}}::{{item.StrainId}}"
+                     value="{{item.error or ''}}" /></td>
+            <td>
+              <input type="text"
+                     name="n-new::{{item.DataId}}::{{item.StrainId}}"
+                     value="{{item.count or ''}}"
+                     data-original-value="{{item.count or "-"}}"
+                     class="form-control" />
+              <input type="hidden"
+                     name="n-original::{{item.DataId}}::{{item.StrainId}}"
+                     value="{{item.count or ''}}" /></td>
+            {%endif%}
+          </tr>
+          {%endfor%}
+        </tbody>
+      </table>
+    </div>
+    <div class="form-group">
+      <div class="col-sm-offset-2 col-sm-10">
+        <input type="submit"
+               name="submit"
+               class="btn btn-primary"
+               value="update data" />
+      </div>
+    </div>
+  </form>
+</div>
+
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/index.html b/uploader/templates/phenotypes/index.html
new file mode 100644
index 0000000..689c28e
--- /dev/null
+++ b/uploader/templates/phenotypes/index.html
@@ -0,0 +1,21 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "species/macro-select-species.html" import select_species_form%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  {{select_species_form(url_for("species.populations.phenotypes.index"), species)}}
+</div>
+{%endblock%}
+
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/species.js"></script>
+{%endblock%}
diff --git a/uploader/templates/phenotypes/job-status.html b/uploader/templates/phenotypes/job-status.html
new file mode 100644
index 0000000..257f726
--- /dev/null
+++ b/uploader/templates/phenotypes/job-status.html
@@ -0,0 +1,155 @@
+{%extends "phenotypes/base.html"%}
+{%from "cli-output.html" import cli_output%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "phenotypes/macro-display-pheno-dataset-card.html" import display_pheno_dataset_card%}
+
+{%block extrameta%}
+{%if job and job.status not in ("success", "completed:success", "error", "completed:error")%}
+<meta http-equiv="refresh" content="5" />
+{%endif%}
+{%endblock%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="add-phenotypes"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">View Datasets</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+
+{%if job%}
+<h4 class="subheading">Progress</h4>
+<div class="row" style="overflow:scroll;">
+  <p><strong>Process Status:</strong> {{job.status}}</p>
+  {%if metadata%}
+  <table class="table table-responsive">
+    <thead>
+      <tr>
+        <th>File</th>
+        <th>Status</th>
+        <th>Lines Processed</th>
+        <th>Total Errors</th>
+      </tr>
+    </thead>
+
+    <tbody>
+      {%for file,meta in metadata.items()%}
+      <tr>
+        <td>{{file}}</td>
+        <td>{{meta.status}}</td>
+        <td>{{meta.linecount}}</td>
+        <td>{{meta["total-errors"]}}</td>
+      </tr>
+      {%endfor%}
+    </tbody>
+  </table>
+  {%endif%}
+</div>
+
+<div class="row">
+  {%if  job.status in ("completed:success", "success")%}
+  <p>
+    {%if errors | length == 0%}
+    <a href="{{url_for('species.populations.phenotypes.review_job_data',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id,
+           job_id=job_id)}}"
+       class="btn btn-primary"
+       title="Continue to process data">Continue</a>
+    {%else%}
+    <span class="text-muted"
+          disabled="disabled"
+          style="border: solid 2px;border-radius: 5px;padding: 0.3em;">
+      Cannot continue due to errors. Please fix the errors first.
+    </span>
+    {%endif%}
+  </p>
+  {%endif%}
+</div>
+
+<h4 class="subheading">Errors</h4>
+<div class="row" style="max-height: 20em; overflow: scroll;">
+  {%if errors | length == 0 %}
+  <p class="text-info">
+    <span class="glyphicon glyphicon-info-sign"></span>
+    No errors found so far
+  </p>
+  {%else%}
+  <table class="table table-responsive">
+    <thead style="position: sticky; top: 0; background: white;">
+      <tr>
+        <th>File</th>
+        <th>Row</th>
+        <th>Column</th>
+        <th>Value</th>
+        <th>Message</th>
+      </tr>
+    </thead>
+
+    <tbody style="font-size: 0.9em;">
+      {%for error in errors%}
+      <tr>
+        <td>{{error.filename}}</td>
+        <td>{{error.rowtitle}}</td>
+        <td>{{error.coltitle}}</td>
+        <td>{%if error.cellvalue is not none and error.cellvalue | length > 25%}
+          {{error.cellvalue[0:24]}}&hellip;
+          {%else%}
+          {{error.cellvalue}}
+          {%endif%}
+        </td>
+        <td>
+          {%if error.message | length > 250 %}
+          {{error.message[0:249]}}&hellip;
+          {%else%}
+          {{error.message}}
+          {%endif%}
+        </td>
+      </tr>
+      {%endfor%}
+    </tbody>
+  </table>
+  {%endif%}
+</div>
+
+<div class="row">
+  {{cli_output(job, "stdout")}}
+</div>
+
+<div class="row">
+  {{cli_output(job, "stderr")}}
+</div>
+
+{%else%}
+<div class="row">
+  <h3 class="text-danger">No Such Job</h3>
+  <p>Could not find a job with the ID: {{job_id}}</p>
+  <p>
+    Please go back to
+    <a href="{{url_for('species.populations.phenotypes.view_dataset',
+             species_id=species.SpeciesId,
+             population_id=population.Id,
+             dataset_id=dataset.Id)}}"
+       title="'{{dataset.Name}}' dataset page">
+      the '{{dataset.Name}}' dataset page</a>
+    to upload new phenotypes or edit existing ones.</p>
+</div>
+{%endif%}
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_pheno_dataset_card(species, population, dataset)}}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/list-datasets.html b/uploader/templates/phenotypes/list-datasets.html
new file mode 100644
index 0000000..2cf2c7f
--- /dev/null
+++ b/uploader/templates/phenotypes/list-datasets.html
@@ -0,0 +1,68 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="list-datasets"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.list_datasets',
+           species_id=species.SpeciesId,
+           population_id=population.Id)}}">List Datasets</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  {%if datasets | length > 0%}
+  <p>The dataset(s) available for this population is/are:</p>
+
+  <table class="table">
+    <thead>
+      <tr>
+        <th>Name</th>
+        <th>Full Name</th>
+        <th>Short Name</th>
+      </tr>
+    </thead>
+
+    <tbody>
+      {%for dataset in datasets%}
+      <tr>
+        <td><a href="{{url_for('species.populations.phenotypes.view_dataset',
+                     species_id=species.SpeciesId,
+                     population_id=population.Id,
+                     dataset_id=dataset.Id)}}">{{dataset.Name}}</a></td>
+        <td>{{dataset.FullName}}</td>
+        <td>{{dataset.ShortName}}</td>
+      </tr>
+      {%endfor%}
+    </tbody>
+  </table>
+  {%else%}
+  <p>Phenotypes need to go into a dataset. We do not currently have a dataset
+    for species <strong>'{{species["FullName"]}} ({{species["Name"]}})'</strong>
+    phenotypes.</p>
+
+  <p>Do, please, create a new dataset by clicking on the "Create Dataset" button
+    below and following the prompts/instructions.</p>
+  <p><a href="{{url_for('species.populations.phenotypes.create_dataset',
+              species_id=species.SpeciesId,
+              population_id=population.Id)}}"
+        class="btn btn-primary"
+        title="Create a new phenotype dataset.">create dataset</a></p>
+  {%endif%}
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/phenotypes/load-phenotypes-success.html b/uploader/templates/phenotypes/load-phenotypes-success.html
new file mode 100644
index 0000000..645be16
--- /dev/null
+++ b/uploader/templates/phenotypes/load-phenotypes-success.html
@@ -0,0 +1,42 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "phenotypes/macro-display-pheno-dataset-card.html" import display_pheno_dataset_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="load-phenotypes-success"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">Add Phenotypes</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+<div class="row">
+  <p>You have successfully loaded
+    <!-- maybe indicate the number of phenotypes here? -->your
+    new phenotypes into the database.</p>
+  <!-- TODO: Maybe notify user that they have sole access. -->
+  <!-- TODO: Maybe provide a link to go to GeneNetwork to view the data. -->
+  <p>View your data
+    <a href="{{search_page_uri}}"
+       target="_blank">on GeneNetwork2</a>.
+    You might need to login to GeneNetwork2 to view specific traits.</p>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_pheno_dataset_card(species, population, dataset)}}
+{%endblock%}
+
+
+{%block more_javascript%}{%endblock%}
diff --git a/uploader/templates/phenotypes/macro-display-pheno-dataset-card.html b/uploader/templates/phenotypes/macro-display-pheno-dataset-card.html
new file mode 100644
index 0000000..11b108b
--- /dev/null
+++ b/uploader/templates/phenotypes/macro-display-pheno-dataset-card.html
@@ -0,0 +1,31 @@
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%macro display_pheno_dataset_card(species, population, dataset)%}
+{{display_population_card(species, population)}}
+
+<div class="card">
+  <div class="card-body">
+    <h5 class="card-title">Phenotypes' Dataset</h5>
+    <div class="card-text">
+      <table class="table">
+        <tbody>
+          <tr>
+            <td>Name</td>
+            <td>{{dataset.Name}}</td>
+          </tr>
+
+          <tr>
+            <td>Full Name</td>
+            <td>{{dataset.FullName}}</td>
+          </tr>
+
+          <tr>
+            <td>Short Name</td>
+            <td>{{dataset.ShortName}}</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+  </div>
+</div>
+{%endmacro%}
diff --git a/uploader/templates/phenotypes/macro-display-preview-table.html b/uploader/templates/phenotypes/macro-display-preview-table.html
new file mode 100644
index 0000000..5a4c422
--- /dev/null
+++ b/uploader/templates/phenotypes/macro-display-preview-table.html
@@ -0,0 +1,19 @@
+{%macro display_preview_table(tableid, filetype)%}
+<div class="card">
+  <div class="card-body">
+    <h5 class="card-title">{{filetype | title}}: File Preview</h5>
+    <div class="card-text" style="overflow: scroll;">
+      <table id="{{tableid}}" class="table table-condensed table-responsive">
+        <thead>
+          <tr>
+          </tr>
+        <tbody>
+          <tr>
+            <td class="data-row-template text-info"></td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+  </div>
+</div>
+{%endmacro%}
diff --git a/uploader/templates/phenotypes/macro-display-resumable-elements.html b/uploader/templates/phenotypes/macro-display-resumable-elements.html
new file mode 100644
index 0000000..ed14ea5
--- /dev/null
+++ b/uploader/templates/phenotypes/macro-display-resumable-elements.html
@@ -0,0 +1,60 @@
+{%macro display_resumable_elements(id, title, help)%}
+<div id="{{id}}"
+     class="resumable-elements visually-hidden"
+     style="background:#D4D4EE;border-radius: 5px;;padding: 1em;border-left: solid #B2B2CC 1px;border-bottom: solid #B2B2CC 2px;margin-top:0.3em;">
+  <strong style="line-height: 1.2em;">{{title | title}}</strong>
+
+  <span class="form-text text-muted">{{help | safe}}</span>
+
+  <div id="{{id}}-selected-files"
+       class="resumable-selected-files"
+       style="display:flex;flex-direction:row;flex-wrap: wrap;justify-content:space-around;gap:10px 20px;">
+    <div class="panel panel-info file-display-template visually-hidden">
+      <div class="panel-heading filename">The Filename Goes Here!</div>
+      <div class="panel-body">
+        <ul>
+          <li>
+            <strong>Name</strong>:
+            <span class="filename">the file's name</span></li>
+
+          <li><strong>Size</strong>: <span class="filesize">0 MB</span></li>
+
+          <li>
+            <strong>Unique Identifier</strong>:
+            <span class="fileuniqueid">brrr</span></li>
+
+          <li>
+            <strong>Mime</strong>:
+            <span class="filemimetype">text/csv</span></li>
+        </ul>
+      </div>
+    </div>
+  </div>
+
+  <a id="{{id}}-browse-button"
+     class="resumable-browse-button btn btn-info"
+     href="#{{id}}"
+     style="margin-left: 80%;">Browse</a>
+
+  <div id="{{id}}-progress-bar" class="progress visually-hidden">
+    <div class="progress-bar"
+         role="progress-bar"
+         aria-valuenow="60"
+         aria-valuemin="0"
+         aria-valuemax="100"
+         style="width: 0%;">
+      Uploading: 60%
+    </div>
+  </div>
+
+  <div id="{{id}}-cancel-resume-buttons">
+    <a id="{{id}}-resume-button"
+       class="resumable-resume-button btn btn-info visually-hidden"
+       href="#">resume upload</a>
+
+    <a id="{{id}}-cancel-button"
+       class="resumable-cancel-button btn btn-danger visually-hidden"
+       href="#">cancel upload</a>
+  </div>
+</div>
+{%endmacro%}
diff --git a/uploader/templates/phenotypes/review-job-data.html b/uploader/templates/phenotypes/review-job-data.html
new file mode 100644
index 0000000..859df74
--- /dev/null
+++ b/uploader/templates/phenotypes/review-job-data.html
@@ -0,0 +1,125 @@
+{%extends "phenotypes/base.html"%}
+{%from "cli-output.html" import cli_output%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "phenotypes/macro-display-pheno-dataset-card.html" import display_pheno_dataset_card%}
+
+{%block extrameta%}
+{%if not job%}
+<meta http-equiv="refresh"
+      content="20; url={{url_for('species.populations.phenotypes.view_dataset', species_id=species.SpeciesId,
+               population_id=population.Id,
+               dataset_id=dataset.Id)}}" />
+{%endif%}
+{%endblock%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="add-phenotypes"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">View Datasets</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+
+{%if job%}
+<div class="row">
+  <h3 class="heading">Data Review</h3>
+  <p class="text-info"><strong>
+      The data has <em>NOT</em> been added/saved yet. Review the details below
+      and click "Continue" to save the data.</strong></p>
+  <p>The &#x201C;<strong>{{dataset.FullName}}</strong>&#x201D; dataset from the
+    &#x201C;<strong>{{population.FullName}}</strong>&#x201D; population of the
+    species &#x201C;<strong>{{species.SpeciesName}} ({{species.FullName}})</strong>&#x201D;
+    will be updated as follows:</p>
+
+  <ul>
+    {%if publication%}
+    <li>All {{summary.get("pheno", {}).get("total-data-rows", "0")}} phenotypes
+      are linked to the following publication:
+      <ul>
+        <li><strong>Publication Title:</strong>
+          {{publication.Title or "—"}}</li>
+        <li><strong>Author(s):</strong>
+          {{publication.Authors or "—"}}</li>
+      </ul>
+    </li>
+    {%endif%}
+  {%for ftype in ("phenocovar", "pheno", "phenose", "phenonum")%}
+  {%if summary.get(ftype, False)%}
+    <li>A total of {{summary[ftype]["number-of-files"]}} files will be processed
+      adding {%if ftype == "phenocovar"%}(possibly){%endif%}
+      {{summary[ftype]["total-data-rows"]}} new
+      {%if ftype == "phenocovar"%}
+      phenotypes
+      {%else%}
+      {{summary[ftype]["description"]}} rows
+      {%endif%}
+      to the database.
+    </li>
+  {%endif%}
+  {%endfor%}
+  </ul>
+
+  <form id="frm-review-phenotype-data"
+        method="POST"
+        action="{{url_for('species.populations.phenotypes.load_data_to_database',
+                species_id=species.SpeciesId,
+                population_id=population.Id,
+                dataset_id=dataset.Id)}}">
+    <input type="hidden" name="data-qc-job-id" value="{{job.jobid}}" />
+    <input type="submit"
+           value="continue"
+           class="btn btn-primary" />
+  </form>
+</div>
+{%else%}
+<div class="row">
+  <h4 class="subheading">Invalid Job</h3>
+  <p class="text-danger">
+    Could not find a job with the ID: <strong>{{job_id}}.</p>
+  <p>You will be redirected in
+    <span id="countdown-element" class="text-info">20</span> second(s)</p>
+  <p class="text-muted">
+    <small>
+      If you are not redirected, please
+      <a href="{{url_for(
+               'species.populations.phenotypes.view_dataset',
+               species_id=species.SpeciesId,
+               population_id=population.Id,
+               dataset_id=dataset.Id)}}">click here</a> to continue
+    </small>
+  </p>
+</div>
+{%endif%}
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_pheno_dataset_card(species, population, dataset)}}
+{%endblock%}
+
+
+{%block javascript%}
+<script type="text/javascript">
+  $(document).ready(function() {
+      var countdown = 20;
+      var countdown_element = $("#countdown-element");
+      if(countdown_element.length === 1) {
+          intv = window.setInterval(function() {
+              countdown = countdown - 1;
+              countdown_element.html(countdown);
+          }, 1000);
+      }
+  });
+</script>
+{%endblock%}
diff --git a/uploader/templates/phenotypes/select-population.html b/uploader/templates/phenotypes/select-population.html
new file mode 100644
index 0000000..48c19b1
--- /dev/null
+++ b/uploader/templates/phenotypes/select-population.html
@@ -0,0 +1,26 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "species/macro-display-species-card.html" import display_species_card%}
+{%from "populations/macro-select-population.html" import select_population_form%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+
+{%block contents%}
+{{flash_all_messages()}}
+
+
+<div class="row">
+  {{select_population_form(url_for("species.populations.phenotypes.select_population", species_id=species.SpeciesId), species, populations)}}
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_species_card(species)}}
+{%endblock%}
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/populations.js"></script>
+{%endblock%}
diff --git a/uploader/templates/phenotypes/view-dataset.html b/uploader/templates/phenotypes/view-dataset.html
new file mode 100644
index 0000000..306dcce
--- /dev/null
+++ b/uploader/templates/phenotypes/view-dataset.html
@@ -0,0 +1,150 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-table-pagination.html" import table_pagination%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="view-dataset"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.view_dataset',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id)}}">View</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <p>The basic dataset details are:</p>
+
+  <table class="table">
+    <thead>
+      <tr>
+        <th>Name</th>
+        <th>Full Name</th>
+        <th>Short Name</th>
+      </tr>
+    </thead>
+
+    <tbody>
+      <tr>
+        <td>{{dataset.Name}}</td>
+        <td>{{dataset.FullName}}</td>
+        <td>{{dataset.ShortName}}</td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+
+<div class="row">
+  <p><a href="{{url_for('species.populations.phenotypes.add_phenotypes',
+              species_id=species.SpeciesId,
+              population_id=population.Id,
+              dataset_id=dataset.Id)}}"
+        title="Add a bunch of phenotypes"
+        class="btn btn-primary">Add phenotypes</a></p>
+</div>
+
+<div class="row">
+  <h2>Phenotype Data</h2>
+
+  <p>Click on any of the phenotypes in the table below to view and edit that
+    phenotype's data.</p>
+  <p>Use the search to filter through all the phenotypes and find specific
+    phenotypes of interest.</p>
+</div>
+
+
+<div class="row">
+
+  <table id="tbl-phenotypes-list" class="table compact stripe cell-border">
+    <thead>
+      <tr>
+        <th></th>
+        <th>Index</th>
+        <th>Record</th>
+        <th>Description</th>
+      </tr>
+    </thead>
+
+    <tbody></tbody>
+  </table>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
+
+
+{%block javascript%}
+<script type="text/javascript">
+  $(function() {
+      var species_id = {{species.SpeciesId}};
+      var population_id = {{population.Id}};
+      var dataset_id = {{dataset.Id}};
+      var dataset_name = "{{dataset.Name}}";
+      var data = {{phenotypes | tojson}};
+
+      var dtPhenotypesList = buildDataTable(
+          "#tbl-phenotypes-list",
+          data,
+          [
+              {
+                  data: function(pheno) {
+                      return `<input type="checkbox" name="selected-phenotypes" `
+                          + `id="chk-selected-phenotypes-${pheno.InbredSetCode}_${pheno.xref_id}" `
+                          + `value="${pheno.InbredSetCode}_${pheno.xref_id}" `
+                          + `class="chk-row-select" />`
+                  }
+              },
+              {data: "sequence_number"},
+              {
+                  data: function(pheno, type, set, meta) {
+                      var spcs_id = {{species.SpeciesId}};
+                      var pop_id = {{population.Id}};
+                      var dtst_id = {{dataset.Id}};
+                      return `<a href="/species/${spcs_id}` +
+                          `/populations/${pop_id}` +
+                          `/phenotypes/datasets/${dtst_id}` +
+                          `/phenotype/${pheno.xref_id}` +
+                          `" target="_blank">` +
+                          `${pheno.InbredSetCode}_${pheno.xref_id}` +
+                          `</a>`;
+                  }
+              },
+              {
+                  data: function(pheno) {
+                      return (pheno.Post_publication_description ||
+                              pheno.Original_description ||
+                              pheno.Pre_publication_description);
+                  }
+              }
+          ],
+          {
+              select: "multi+shift",
+              layout: {
+                  top1Start: {
+                      pageLength: {
+                          text: "Show _MENU_ of _TOTAL_"
+                      }
+                  },
+                  topStart: "info",
+                  top1End: null
+              },
+              rowId: function(pheno) {
+                  return `${pheno.InbredSetCode}_${pheno.xref_id}`;
+              }
+          });
+  });
+</script>
+{%endblock%}
diff --git a/uploader/templates/phenotypes/view-phenotype.html b/uploader/templates/phenotypes/view-phenotype.html
new file mode 100644
index 0000000..21ac501
--- /dev/null
+++ b/uploader/templates/phenotypes/view-phenotype.html
@@ -0,0 +1,135 @@
+{%extends "phenotypes/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "populations/macro-display-population-card.html" import display_population_card%}
+
+{%block title%}Phenotypes{%endblock%}
+
+{%block pagetitle%}Phenotypes{%endblock%}
+
+{%block lvl4_breadcrumbs%}
+<li {%if activelink=="view-phenotype"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.phenotypes.view_phenotype',
+           species_id=species.SpeciesId,
+           population_id=population.Id,
+           dataset_id=dataset.Id,
+           xref_id=xref_id)}}">View Phenotype</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <div class="panel panel-default">
+    <div class="panel-heading"><strong>Basic Phenotype Details</strong></div>
+
+    <table class="table">
+      <tbody>
+        <tr>
+          <td><strong>Phenotype</strong></td>
+          <td>{{phenotype.Post_publication_description or phenotype.Pre_publication_abbreviation or phenotype.Original_description}}
+        </tr>
+        <tr>
+          <td><strong>Database</strong></td>
+          <td>{{dataset.FullName}}</td>
+        </tr>
+        <tr>
+          <td><strong>Units</strong></td>
+          <td>{{phenotype.Units}}</td>
+        </tr>
+        {%for key,value in publish_data.items()%}
+        <tr>
+          <td><strong>{{key}}</strong></td>
+          <td>{{value}}</td>
+        </tr>
+        {%else%}
+        <tr>
+          <td colspan="2" class="text-muted">
+            <span class="glyphicon glyphicon-exclamation-sign"></span>
+            No publication data found.
+          </td>
+        </tr>
+        {%endfor%}
+      </tbody>
+    </table>
+  </div>
+</div>
+
+{%if "group:resource:edit-resource" in privileges
+or "group:resource:delete-resource" in privileges%}
+<div class="row">
+  <div class="btn-group btn-group-justified">
+    <div class="btn-group">
+      {%if "group:resource:edit-resource" in privileges%}
+      <a href="{{url_for('species.populations.phenotypes.edit_phenotype_data',
+               species_id=species.SpeciesId,
+               population_id=population.Id,
+               dataset_id=dataset.Id,
+               xref_id=xref_id)}}"
+         title="Edit the values for the phenotype. This is meant to be used when you need to update only a few values."
+         class="btn btn-primary">Edit</a>
+      {%endif%}
+    </div>
+    <div class="btn-group"></div>
+    <div class="btn-group">
+      {%if "group:resource:delete-resource" in privileges%}
+      <a href="#"
+         title="Delete the entire phenotype. This is useful when you need to change data for most or all of the fields for this phenotype."
+         class="btn btn-danger not-implemented"
+         disabled="disabled">delete</a>
+      {%endif%}
+    </div>
+  </div>
+</div>
+{%endif%}
+
+<div class="row">
+  <div class="panel panel-default">
+    <div class="panel-heading"><strong>Phenotype Data</strong></div>
+    {%if "group:resource:view-resource" in privileges%}
+    <table class="table">
+      <thead>
+        <tr>
+          <th>#</th>
+          <th>Sample</th>
+          <th>Value</th>
+          {%if has_se%}
+          <th>SE</th>
+          <th>N</th>
+          {%endif%}
+        </tr>
+      </thead>
+
+      <tbody>
+        {%for item in phenotype.data%}
+        <tr>
+          <td>{{loop.index}}</td>
+          <td>{{item.StrainName}}</td>
+          <td>{{item.value}}</td>
+          {%if has_se%}
+          <td>{{item.error or "-"}}</td>
+          <td>{{item.count or "-"}}</td>
+          {%endif%}
+        </tr>
+        {%endfor%}
+      </tbody>
+    </table>
+    {%else%}
+    <p class="text-danger">
+      <span class="glyphicon glyphicon-exclamation-sign"></span>
+      You do not currently have privileges to view this phenotype in greater
+      detail.
+    </p>
+    {%endif%}
+  </div>
+</div>
+
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_population_card(species, population)}}
+{%endblock%}
diff --git a/uploader/templates/platforms/base.html b/uploader/templates/platforms/base.html
new file mode 100644
index 0000000..dac965f
--- /dev/null
+++ b/uploader/templates/platforms/base.html
@@ -0,0 +1,13 @@
+{%extends "species/base.html"%}
+
+{%block lvl3_breadcrumbs%}
+<li {%if activelink=="platforms"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.populations.platforms.index')}}">
+    Sequencing Platforms</a>
+</li>
+{%block lvl4_breadcrumbs%}{%endblock%}
+{%endblock%}
diff --git a/uploader/templates/platforms/create-platform.html b/uploader/templates/platforms/create-platform.html
new file mode 100644
index 0000000..0866d5e
--- /dev/null
+++ b/uploader/templates/platforms/create-platform.html
@@ -0,0 +1,124 @@
+{%extends "platforms/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "species/macro-display-species-card.html" import display_species_card%}
+
+{%block title%}Platforms &mdash; Create Platforms{%endblock%}
+
+{%block pagetitle%}Platforms &mdash; Create Platforms{%endblock%}
+
+{%block lvl3_breadcrumbs%}
+<li {%if activelink=="create-platform"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.platforms.create_platform',
+           species_id=species.SpeciesId)}}">create platform</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <h2>Create New Platform</h2>
+
+  <p>You can create a new genetic sequencing platform below.</p>
+</div>
+
+<div class="row">
+  <form id="frm-create-platform"
+        method="POST"
+        action="{{url_for('species.platforms.create_platform',
+                species_id=species.SpeciesId)}}">
+
+    <div class="form-group">
+      <label for="txt-geo-platform" class="form-label">GEO Platform</label>
+      <input type="text"
+             id="txt-geo-platform"
+             name="geo-platform"
+             required="required"
+             class="form-control"  />
+      <small class="form-text text-muted">
+        <p>This is the platform's
+          <a href="https://www.ncbi.nlm.nih.gov/geo/browse/?view=platforms&tax={{species.TaxonomyId}}"
+             title="Platforms for '{{species.FullName}}' on NCBI">
+            accession value on NCBI</a>. If you do not know the value, click the
+          link and search on NCBI for species '{{species.FullName}}'.</p></small>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-platform-name" class="form-label">Platform Name</label>
+      <input type="text"
+             id="txt-platform-name"
+             name="platform-name"
+             required="required"
+             class="form-control" />
+      <small class="form-text text-muted">
+        <p>This is name of the genetic sequencing platform.</p></small>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-platform-shortname" class="form-label">
+        Platform Short Name</label>
+      <input type="text"
+             id="txt-platform-shortname"
+             name="platform-shortname"
+             required="required"
+             class="form-control" />
+      <small class="form-text text-muted">
+        <p>Use the following conventions for this field:
+          <ol>
+            <li>Start with a 4-letter vendor code, e.g. "Affy" for "Affymetrix", "Illu" for "Illumina", etc.</li>
+            <li>Append an underscore to the 4-letter vendor code</li>
+            <li>Use the name of the array given by the vendor, e.g.  U74AV2, MOE430A, etc.</li>
+          </ol>
+        </p>
+      </small>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-platform-title" class="form-label">Platform Title</label>
+      <input type="text"
+             id="txt-platform-title"
+             name="platform-title"
+             required="required"
+             class="form-control"  />
+      <small class="form-text text-muted">
+        <p>The full platform title. Sometimes, this is the same as the Platform
+          Name above.</p></small>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-go-tree-value" class="form-label">GO Tree Value</label>
+      <input type="text"
+             id="txt-go-tree-value"
+             name="go-tree-value"
+             class="form-control"  />
+      <small class="form-text text-muted">
+        <p>This is a Chip identification value useful for analysis with the
+          <strong>
+            <a href="https://www.geneweaver.org/"
+               title="Go to the GeneWeaver site."
+               target="_blank">GeneWeaver</a></strong>
+          and
+          <strong>
+            <a href="https://www.webgestalt.org/"
+               title="Go to the WEB-based GEne SeT AnaLysis Toolkit site."
+               target="_blank">WebGestalt</a></strong>
+          tools.<br />
+        This can be left blank for custom platforms.</p></small>
+    </div>
+
+    <div class="form-group">
+      <input type="submit"
+             value="create new platform"
+             class="btn btn-primary"  />
+    </div>
+  </form>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_species_card(species)}}
+{%endblock%}
diff --git a/uploader/templates/platforms/index.html b/uploader/templates/platforms/index.html
new file mode 100644
index 0000000..555b444
--- /dev/null
+++ b/uploader/templates/platforms/index.html
@@ -0,0 +1,25 @@
+{%extends "platforms/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "species/macro-select-species.html" import select_species_form%}
+
+{%block title%}Platforms{%endblock%}
+
+{%block pagetitle%}Platforms{%endblock%}
+
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <p>In this section, you will be able to view and manage the sequencing
+    platforms that are currently supported by GeneNetwork.</p>
+</div>
+
+<div class="row">
+  {{select_species_form(url_for("species.platforms.index"), species)}}
+</div>
+{%endblock%}
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/species.js"></script>
+{%endblock%}
diff --git a/uploader/templates/platforms/list-platforms.html b/uploader/templates/platforms/list-platforms.html
new file mode 100644
index 0000000..a6bcfdc
--- /dev/null
+++ b/uploader/templates/platforms/list-platforms.html
@@ -0,0 +1,93 @@
+{%extends "platforms/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+{%from "species/macro-display-species-card.html" import display_species_card%}
+
+{%block title%}Platforms &mdash; List Platforms{%endblock%}
+
+{%block pagetitle%}Platforms &mdash; List Platforms{%endblock%}
+
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <p>View the list of the genetic sequencing platforms that are currently
+    supported by GeneNetwork.</p>
+  <p>If you cannot find the platform you wish to use, you can add it by clicking
+    the "New Platform" button below.</p>
+  <p><a href="{{url_for('species.platforms.create_platform',
+              species_id=species.SpeciesId)}}"
+        title="Create a new genetic sequencing platform for species {{species.FullName}}"
+        class="btn btn-primary">Create Platform</a></p>
+</div>
+
+<div class="row">
+  <h2>Supported Platforms</h2>
+  {%if platforms is defined and platforms | length > 0%}
+  <p>There are {{total_platforms}} platforms supported by GeneNetwork</p>
+
+  <div class="row">
+    <div class="col-md-2" style="text-align: start;">
+      {%if start_from > 0%}
+      <a href="{{url_for('species.platforms.list_platforms',
+               species_id=species.SpeciesId,
+               start_from=start_from-count,
+               count=count)}}">
+        <span class="glyphicon glyphicon-backward"></span>
+        Previous
+      </a>
+      {%endif%}
+    </div>
+    <div class="col-md-8" style="text-align: center;">
+      Displaying platforms {{start_from+1}} to {{start_from+count if start_from+count < total_platforms else total_platforms}} of
+      {{total_platforms}}
+    </div>
+    <div class="col-md-2" style="text-align: end;">
+      {%if start_from + count < total_platforms%}
+      <a href="{{url_for('species.platforms.list_platforms',
+               species_id=species.SpeciesId,
+               start_from=start_from+count,
+               count=count)}}">
+        Next
+        <span class="glyphicon glyphicon-forward"></span>
+      </a>
+      {%endif%}
+    </div>
+  </div>
+
+  <table class="table">
+    <thead>
+      <tr>
+        <th></th>
+        <th>Platform Name</th>
+        <th><a href="https://www.ncbi.nlm.nih.gov/geo/browse/?view=platforms&tax={{species.TaxonomyId}}"
+               title="Gene Expression Omnibus: Platforms section"
+               target="_blank">GEO Platform</a></th>
+        <th>Title</th>
+      </tr>
+    </thead>
+
+    <tbody>
+      {%for platform in platforms%}
+      <tr>
+        <td>{{platform.sequence_number}}</td>
+        <td>{{platform.GeneChipName}}</td>
+        <td><a href="https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={{platform.GeoPlatform}}"
+               title="View platform on the Gene Expression Omnibus"
+               target="_blank">{{platform.GeoPlatform}}</a></td>
+        <td>{{platform.Title}}</td>
+      </tr>
+      {%endfor%}
+    </tbody>
+  </table>
+  {%else%}
+  <p class="text-warning">
+    <span class="glyphicon glyphicon-exclamation-sign"></span>
+    There are no platforms supported at this time!</p>
+  {%endif%}
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_species_card(species)}}
+{%endblock%}
diff --git a/uploader/templates/populations/base.html b/uploader/templates/populations/base.html
index d763fc1..9db8083 100644
--- a/uploader/templates/populations/base.html
+++ b/uploader/templates/populations/base.html
@@ -6,7 +6,13 @@
     {%else%}
     class="breadcrumb-item"
     {%endif%}>
+  {%if population is mapping%}
+  <a href="{{url_for('species.populations.view_population',
+           species_id=species.SpeciesId,
+           population_id=population.Id)}}">{{population.Name}}</a>
+  {%else%}
   <a href="{{url_for('species.populations.index')}}">Populations</a>
+  {%endif%}
 </li>
 {%block lvl3_breadcrumbs%}{%endblock%}
 {%endblock%}
diff --git a/uploader/templates/populations/create-population.html b/uploader/templates/populations/create-population.html
index b05ce37..007b6bf 100644
--- a/uploader/templates/populations/create-population.html
+++ b/uploader/templates/populations/create-population.html
@@ -37,12 +37,15 @@
 <div class="row">
   <form method="POST"
         action="{{url_for('species.populations.create_population',
-                species_id=species.SpeciesId)}}">
+                species_id=species.SpeciesId,
+                return_to=return_to)}}">
 
     <legend>Create Population</legend>
 
     {{flash_all_messages()}}
 
+    <input type="hidden" name="return_to" value="{{return_to}}">
+
     <div {%if errors.population_fullname%}
          class="form-group has-error"
          {%else%}
@@ -107,9 +110,12 @@
              value="{{error_values.population_code or ''}}"
              class="form-control" />
       <small class="form-text text-muted">
-        <p class="text-danger">
-          <span class="glyphicon glyphicon-exclamation-sign"></span>
-          What is this field is for? Confirm with Arthur and the rest.
+        <p class="form-text text-muted">
+          This is a 3-character code for your population, that is prepended to
+          the phenotype identifiers. e.g. For the "BXD Family" population, the
+          code is "BXD" and therefore, the phenotype identifiers for the
+          population look like the following examples: <em>BXD_10148</em>,
+          <em>BXD_10180</em>, <em>BXD_10197</em>, etc.
         </p>
       </small>
     </div>
@@ -148,24 +154,35 @@
          {%else%}
          class="form-group"
          {%endif%}>
-      <label for="select-population-family" class="form-label">Family</label>
-      <select id="select-population-family"
-              name="population_family"
-              class="form-control"
-              required="required">
-        <option value="">Please select a family</option>
+      <label for="txt-population-family" class="form-label">Family</label>
+      <input type="text"
+             id="txt-population-family"
+             name="population_family"
+             class="form-control"
+             list="families-list" />
+      <datalist id="families-list">
         {%for family in families%}
-        <option value="{{family}}"
-                {%if error_values.population_family == family%}
-                selected="selected"
-                {%endif%}>{{family}}</option>
+        <option value="{{family}}">{{family}}</option>
         {%endfor%}
-      </select>
+      </datalist>
       <small class="form-text text-muted">
         <p>
-          This is a rough grouping of the populations in GeneNetwork into lists
-          of common types of populations.
-        </p>
+          This is <strong>optional</strong> metadata. It is used to group
+          populations into "families" for presentation in the menus.
+          {%if families | length > 0%}
+          Examples of currently existing families are:
+          <ul>
+            {%for family in families[0:7]%}
+            <li>{{family}}</li>
+            {%endfor%}
+            <li>etc.</li>
+          </ul>
+          {%endif%}
+
+          You can
+          {%if families|length>0%} select from existing families, or {%endif%}
+          create a new family by typing in the input box above. You can also
+          leave the family blank.</p>
       </small>
     </div>
 
diff --git a/uploader/templates/populations/index.html b/uploader/templates/populations/index.html
index 4354e02..d2bee77 100644
--- a/uploader/templates/populations/index.html
+++ b/uploader/templates/populations/index.html
@@ -22,3 +22,7 @@
   {{select_species_form(url_for("species.populations.index"), species)}}
 </div>
 {%endblock%}
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/species.js"></script>
+{%endblock%}
diff --git a/uploader/templates/populations/list-populations.html b/uploader/templates/populations/list-populations.html
index 7c7145f..f780e94 100644
--- a/uploader/templates/populations/list-populations.html
+++ b/uploader/templates/populations/list-populations.html
@@ -51,7 +51,7 @@
     <caption>Populations for {{species.FullName}}</caption>
     <thead>
       <tr>
-        <th>#</th>
+        <th></th>
         <th>Name</th>
         <th>Full Name</th>
         <th>Description</th>
diff --git a/uploader/templates/populations/macro-display-population-card.html b/uploader/templates/populations/macro-display-population-card.html
index e68f8e3..16b477f 100644
--- a/uploader/templates/populations/macro-display-population-card.html
+++ b/uploader/templates/populations/macro-display-population-card.html
@@ -7,25 +7,34 @@
   <div class="card-body">
     <h5 class="card-title">Population</h5>
     <div class="card-text">
-      <dl>
-        <dt>Name</dt>
-        <dd>{{population.Name}}</dd>
+      <table class="table">
+        <tbody>
+          <tr>
+            <td>Name</td>
+            <td>{{population.Name}}</td>
+          </tr>
 
-        <dt>Full Name</dt>
-        <dd>{{population.FullName}}</dd>
+          <tr>
+            <td>Full Name</td>
+            <td>{{population.FullName}}</td>
+          </tr>
 
-        <dt>Code</dt>
-        <dd>{{population.InbredSetCode}}</dd>
+          <tr>
+            <td>Code</td>
+            <td>{{population.InbredSetCode}}</td>
+          </tr>
 
-        <dt>Genetic Type</dt>
-        <dd>{{population.GeneticType}}</dd>
+          <tr>
+            <td>Genetic Type</td>
+            <td>{{population.GeneticType}}</td>
+          </tr>
 
-        <dt>Family</dt>
-        <dd>{{population.Family}}</dd>
-
-        <dt>Description</dt>
-        <dd>{{population.Description or "-"}}</dd>
-      </dl>
+          <tr>
+            <td>Family</td>
+            <td>{{population.Family}}</td>
+          </tr>
+        </tbody>
+      </table>
     </div>
   </div>
 </div>
diff --git a/uploader/templates/populations/macro-select-population.html b/uploader/templates/populations/macro-select-population.html
index af4fd3a..14b0510 100644
--- a/uploader/templates/populations/macro-select-population.html
+++ b/uploader/templates/populations/macro-select-population.html
@@ -1,30 +1,52 @@
-{%macro select_population_form(form_action, populations)%}
-<form method="GET" action="{{form_action}}">
-  <legend>Select Population</legend>
-
-  <div class="form-group">
-    <label for="select-population" class="form-label">Select Population</label>
-    <select id="select-population"
-            name="population_id"
-            class="form-control"
-            required="required">
-      <option value="">Select Population</option>
-      {%for family in populations%}
-      <optgroup {%if family[0][1] is not none%}
-                label="{{family[0][1]}}"
-                {%else%}
-                label="Undefined"
-                {%endif%}>
-        {%for population in family[1]%}
-        <option value="{{population.Id}}">{{population.FullName}}</option>
-        {%endfor%}
-      </optgroup>
-      {%endfor%}
-    </select>
+{%from "macro-step-indicator.html" import step_indicator%}
+
+{%macro select_population_form(form_action, species, populations)%}
+<form method="GET" action="{{form_action}}" class="form-horizontal">
+
+  <h2>{{step_indicator("2")}} What population do you want to work with?</h2>
+
+  {%if populations | length != 0%}
+
+  <p class="form-text">Search for, and select the population from the table
+    below and click "Continue"</p>
+
+  <div class="radio">
+    <label class="control-label" for="rdo-cant-find-population">
+      <input type="radio" id="rdo-cant-find-population"
+             name="population_id" value="CREATE-POPULATION" />
+      I cannot find the population I want &mdash; create it!
+    </label>
+  </div>
+
+  <div class="col-sm-offset-10 col-sm-2">
+    <input type="submit" value="continue" class="btn btn-primary" />
+  </div>
+
+  <div style="margin-top:3em;">
+    <table id="tbl-select-population" class="table compact stripe"
+           data-populations-list='{{populations | tojson}}'>
+      <thead>
+        <tr>
+          <th></th>
+          <th>Population</th>
+        </tr>
+      </thead>
+
+      <tbody></tbody>
+    </table>
   </div>
 
-  <div class="form-group">
-    <input type="submit" value="Select" class="btn btn-primary" />
+  {%else%}
+  <p class="form-text">
+    There are no populations currently defined for {{species['FullName']}}
+    ({{species['SpeciesName']}}).<br />
+    Click "Continue" to create the first!</p>
+  <input type="hidden" name="population_id" value="CREATE-POPULATION" />
+
+  <div class="col-sm-offset-10 col-sm-2">
+    <input type="submit" value="continue" class="btn btn-primary" />
   </div>
+  {%endif%}
+
 </form>
 {%endmacro%}
diff --git a/uploader/templates/rqtl2/create-tissue-success.html b/uploader/templates/populations/rqtl2/create-tissue-success.html
index d6fe154..d6fe154 100644
--- a/uploader/templates/rqtl2/create-tissue-success.html
+++ b/uploader/templates/populations/rqtl2/create-tissue-success.html
diff --git a/uploader/templates/populations/rqtl2/index.html b/uploader/templates/populations/rqtl2/index.html
new file mode 100644
index 0000000..ec6ffb8
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/index.html
@@ -0,0 +1,54 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Data Upload{%endblock%}
+
+{%block contents%}
+<h1 class="heading">R/qtl2 data upload</h1>
+
+<h2>R/qtl2 Upload</h2>
+
+<div class="row">
+  <form method="POST" action="{{url_for('expression-data.rqtl2.select_species')}}"
+        id="frm-rqtl2-upload">
+    <legend class="heading">upload R/qtl2 bundle</legend>
+    {{flash_messages("error-rqtl2")}}
+
+    <div class="form-group">
+      <label for="select:species" class="form-label">Species</label>
+      <select id="select:species"
+              name="species_id"
+              required="required"
+              class="form-control">
+        <option value="">Select species</option>
+        {%for spec in species%}
+        <option value="{{spec.SpeciesId}}">{{spec.MenuName}}</option>
+        {%endfor%}
+      </select>
+      <small class="form-text text-muted">
+        Data that you upload to the system should belong to a know species.
+        Here you can select the species that you wish to upload data for.
+      </small>
+    </div>
+
+    <input type="submit" class="btn btn-primary" value="submit" />
+  </form>
+</div>
+
+<div class="row">
+  <h2 class="heading">R/qtl2 Bundles</h2>
+
+  <div class="explainer">
+    <p>This feature combines and extends the two upload methods below. Instead of
+      uploading one item at a time, the R/qtl2 bundle you upload can contain both
+      the genotypes data (samples/individuals/cases and their data) and the
+      expression data.</p>
+    <p>The R/qtl2 bundle, additionally, can contain extra metadata, that neither
+      of the methods below can handle.</p>
+
+    <a href="{{url_for('expression-data.rqtl2.select_species')}}"
+       title="Upload a zip bundle of R/qtl2 files">
+      <button class="btn btn-primary">upload R/qtl2 bundle</button></a>
+  </div>
+</div>
+{%endblock%}
diff --git a/uploader/templates/rqtl2/no-such-job.html b/uploader/templates/populations/rqtl2/no-such-job.html
index b17004f..b17004f 100644
--- a/uploader/templates/rqtl2/no-such-job.html
+++ b/uploader/templates/populations/rqtl2/no-such-job.html
diff --git a/uploader/templates/rqtl2/rqtl2-job-error.html b/uploader/templates/populations/rqtl2/rqtl2-job-error.html
index 9817518..9817518 100644
--- a/uploader/templates/rqtl2/rqtl2-job-error.html
+++ b/uploader/templates/populations/rqtl2/rqtl2-job-error.html
diff --git a/uploader/templates/rqtl2/rqtl2-job-results.html b/uploader/templates/populations/rqtl2/rqtl2-job-results.html
index 4ecd415..4ecd415 100644
--- a/uploader/templates/rqtl2/rqtl2-job-results.html
+++ b/uploader/templates/populations/rqtl2/rqtl2-job-results.html
diff --git a/uploader/templates/rqtl2/rqtl2-job-status.html b/uploader/templates/populations/rqtl2/rqtl2-job-status.html
index e896f88..e896f88 100644
--- a/uploader/templates/rqtl2/rqtl2-job-status.html
+++ b/uploader/templates/populations/rqtl2/rqtl2-job-status.html
diff --git a/uploader/templates/rqtl2/rqtl2-qc-job-error.html b/uploader/templates/populations/rqtl2/rqtl2-qc-job-error.html
index 90e8887..90e8887 100644
--- a/uploader/templates/rqtl2/rqtl2-qc-job-error.html
+++ b/uploader/templates/populations/rqtl2/rqtl2-qc-job-error.html
diff --git a/uploader/templates/rqtl2/rqtl2-qc-job-results.html b/uploader/templates/populations/rqtl2/rqtl2-qc-job-results.html
index b3c3a8f..b3c3a8f 100644
--- a/uploader/templates/rqtl2/rqtl2-qc-job-results.html
+++ b/uploader/templates/populations/rqtl2/rqtl2-qc-job-results.html
diff --git a/uploader/templates/rqtl2/rqtl2-qc-job-status.html b/uploader/templates/populations/rqtl2/rqtl2-qc-job-status.html
index f4a6266..f4a6266 100644
--- a/uploader/templates/rqtl2/rqtl2-qc-job-status.html
+++ b/uploader/templates/populations/rqtl2/rqtl2-qc-job-status.html
diff --git a/uploader/templates/rqtl2/rqtl2-qc-job-success.html b/uploader/templates/populations/rqtl2/rqtl2-qc-job-success.html
index f126835..f126835 100644
--- a/uploader/templates/rqtl2/rqtl2-qc-job-success.html
+++ b/uploader/templates/populations/rqtl2/rqtl2-qc-job-success.html
diff --git a/uploader/templates/populations/rqtl2/select-geno-dataset.html b/uploader/templates/populations/rqtl2/select-geno-dataset.html
new file mode 100644
index 0000000..3233abc
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/select-geno-dataset.html
@@ -0,0 +1,69 @@
+{%extends "base.html"%}
+{%from "flash_messages.html" import flash_messages%}
+
+{%block title%}Upload R/qtl2 Bundle{%endblock%}
+
+{%block contents%}
+<h2 class="heading">Select Genotypes Dataset</h2>
+
+<div class="row">
+  <p>Your R/qtl2 files bundle could contain a "geno" specification. You will
+    therefore need to select from one of the existing Genotype datasets or
+    create a new one.</p>
+  <p>This is the dataset where your data will be organised under.</p>
+</div>
+
+<div class="row">
+  <form id="frm-upload-rqtl2-bundle"
+        action="{{url_for('expression-data.rqtl2.select_geno_dataset',
+	        species_id=species.SpeciesId,
+	        population_id=population.InbredSetId)}}"
+        method="POST"
+        enctype="multipart/form-data">
+    <legend class="heading">select from existing genotype datasets</legend>
+
+    <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+    <input type="hidden" name="population_id"
+	   value="{{population.InbredSetId}}" />
+    <input type="hidden" name="rqtl2_bundle_file"
+	   value="{{rqtl2_bundle_file}}" />
+
+    {{flash_messages("error-rqtl2-select-geno-dataset")}}
+
+    <div class="form-group">
+      <legend>Datasets</legend>
+      <label for="select:geno-datasets" class="form-label">Dataset</label>
+      <select id="select:geno-datasets"
+	      name="geno-dataset-id"
+	      required="required"
+	      {%if datasets | length == 0%}
+	      disabled="disabled"
+	      {%endif%}
+              class="form-control"
+              aria-describedby="help-geno-dataset-select-dataset">
+        <option value="">Select dataset</option>
+        {%for dset in datasets%}
+        <option value="{{dset['Id']}}">{{dset["Name"]}} ({{dset["FullName"]}})</option>
+        {%endfor%}
+      </select>
+      <span id="help-geno-dataset-select-dataset" class="form-text text-muted">
+        Select from the existing genotype datasets for species
+        {{species.SpeciesName}} ({{species.FullName}}).
+      </span>
+    </div>
+
+    <button type="submit" class="btn btn-primary">select dataset</button>
+  </form>
+</div>
+
+<div class="row">
+  <p>If the genotype dataset you need does not currently exist for your dataset,
+    go the <a href="{{url_for(
+                    'species.populations.genotypes.create_dataset',
+                    species_id=species.SpeciesId,
+                    population_id=population.Id)}}"
+              title="Create a new genotypes dataset for {{species.FullName}}">
+      genotypes page to create the genotype dataset</a></p>
+</div>
+
+{%endblock%}
diff --git a/uploader/templates/populations/rqtl2/select-population.html b/uploader/templates/populations/rqtl2/select-population.html
new file mode 100644
index 0000000..ded425f
--- /dev/null
+++ b/uploader/templates/populations/rqtl2/select-population.html
@@ -0,0 +1,57 @@
+{%extends "expression-data/index.html"%}
+{%from "flash_messages.html" import flash_messages%}
+{%from "species/macro-display-species-card.html" import display_species_card%}
+
+{%block title%}Select Grouping/Population{%endblock%}
+
+{%block contents%}
+<h1 class="heading">Select grouping/population</h1>
+
+<div class="row">
+  <p>The data is organised in a hierarchical form, beginning with
+    <em>species</em> at the very top. Under <em>species</em> the data is
+    organised by <em>population</em>, sometimes referred to as <em>grouping</em>.
+    (In some really old documents/systems, you might see this referred to as
+    <em>InbredSet</em>.)</p>
+  <p>In this section, you get to define what population your data is to be
+    organised by.</p>
+</div>
+
+<div class="row">
+  <form method="POST"
+        action="{{url_for('expression-data.rqtl2.select_population',
+                species_id=species.SpeciesId)}}">
+    <legend class="heading">select grouping/population</legend>
+    {{flash_messages("error-select-population")}}
+
+    <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+
+    <div class="form-group">
+      <label for="select:inbredset" class="form-label">population</label>
+      <select id="select:inbredset"
+	      name="inbredset_id"
+	      required="required"
+	      class="form-control">
+        <option value="">Select a grouping/population</option>
+        {%for pop in populations%}
+        <option value="{{pop.InbredSetId}}">
+	  {{pop.InbredSetName}} ({{pop.FullName}})</option>
+        {%endfor%}
+      </select>
+      <span class="form-text text-muted">Select the population for your data from
+        the list below.</span>
+    </div>
+
+    <button type="submit" class="btn btn-primary" />select population</button>
+</form>
+</div>
+
+{%endblock%}
+
+{%block sidebarcontents%}
+{{display_species_card(species)}}
+{%endblock%}
+
+
+{%block javascript%}
+{%endblock%}
diff --git a/uploader/templates/rqtl2/select-probeset-dataset.html b/uploader/templates/populations/rqtl2/select-probeset-dataset.html
index 74f8f69..74f8f69 100644
--- a/uploader/templates/rqtl2/select-probeset-dataset.html
+++ b/uploader/templates/populations/rqtl2/select-probeset-dataset.html
diff --git a/uploader/templates/rqtl2/select-probeset-study-id.html b/uploader/templates/populations/rqtl2/select-probeset-study-id.html
index e3fd9cc..e3fd9cc 100644
--- a/uploader/templates/rqtl2/select-probeset-study-id.html
+++ b/uploader/templates/populations/rqtl2/select-probeset-study-id.html
diff --git a/uploader/templates/rqtl2/select-tissue.html b/uploader/templates/populations/rqtl2/select-tissue.html
index fe3080a..fe3080a 100644
--- a/uploader/templates/rqtl2/select-tissue.html
+++ b/uploader/templates/populations/rqtl2/select-tissue.html
diff --git a/uploader/templates/rqtl2/summary-info.html b/uploader/templates/populations/rqtl2/summary-info.html
index 0adba2e..0adba2e 100644
--- a/uploader/templates/rqtl2/summary-info.html
+++ b/uploader/templates/populations/rqtl2/summary-info.html
diff --git a/uploader/templates/rqtl2/upload-rqtl2-bundle-step-01.html b/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-01.html
index 9d45c5f..9d45c5f 100644
--- a/uploader/templates/rqtl2/upload-rqtl2-bundle-step-01.html
+++ b/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-01.html
diff --git a/uploader/templates/rqtl2/upload-rqtl2-bundle-step-02.html b/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-02.html
index 8210ed0..8210ed0 100644
--- a/uploader/templates/rqtl2/upload-rqtl2-bundle-step-02.html
+++ b/uploader/templates/populations/rqtl2/upload-rqtl2-bundle-step-02.html
diff --git a/uploader/templates/populations/view-population.html b/uploader/templates/populations/view-population.html
index 1e2964e..b23caeb 100644
--- a/uploader/templates/populations/view-population.html
+++ b/uploader/templates/populations/view-population.html
@@ -15,7 +15,7 @@
     {%endif%}>
   <a href="{{url_for('species.populations.view_population',
            species_id=species.SpeciesId,
-           population_id=population.InbredSetId)}}">view population</a>
+           population_id=population.InbredSetId)}}">view</a>
 </li>
 {%endblock%}
 
@@ -62,29 +62,35 @@
   <nav class="nav">
     <ul>
       <li>
-        <a href="{{url_for('species.populations.genotypes.list_genotypes',
+        <a href="{{url_for('species.populations.samples.list_samples',
                  species_id=species.SpeciesId,
                  population_id=population.Id)}}"
-           title="Upload genotypes for {{species.FullName}}">Upload Genotypes</a>
+           title="Manage samples: Add new or delete existing.">
+          manage samples</a>
       </li>
       <li>
-        <a href="{{url_for('species.populations.samples.list_samples',
+        <a href="{{url_for('species.populations.genotypes.list_genotypes',
                  species_id=species.SpeciesId,
                  population_id=population.Id)}}"
-           title="Manage samples: Add new or delete existing.">
-          manage samples</a>
+           title="Manage genotypes for {{species.FullName}}">Manage Genotypes</a>
       </li>
       <li>
-        <a href="#" title="Upload expression data">upload expression data</a>
+        <a href="{{url_for('species.populations.phenotypes.list_datasets',
+                 species_id=species.SpeciesId,
+                 population_id=population.Id)}}"
+           title="Manage phenotype data.">manage phenotype data</a>
       </li>
       <li>
-        <a href="#" title="Upload phenotype data">upload phenotype data</a>
+        <a href="#" title="Manage expression data"
+           class="not-implemented">manage expression data</a>
       </li>
       <li>
-        <a href="#" title="Upload individual data">upload individual data</a>
+        <a href="#" title="Manage individual data"
+           class="not-implemented">manage individual data</a>
       </li>
       <li>
-        <a href="#" title="Upload RNA-Seq data">upload RNA-Seq data</a>
+        <a href="#" title="Manage RNA-Seq data"
+           class="not-implemented">manage RNA-Seq data</a>
       </li>
     </ul>
   </nav>
diff --git a/uploader/templates/publications/base.html b/uploader/templates/publications/base.html
new file mode 100644
index 0000000..db80bfa
--- /dev/null
+++ b/uploader/templates/publications/base.html
@@ -0,0 +1,12 @@
+{%extends "base.html"%}
+
+{%block lvl1_breadcrumbs%}
+<li {%if activelink=="publications"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('publications.index')}}">Publications</a>
+</li>
+{%block lvl2_breadcrumbs%}{%endblock%}
+{%endblock%}
diff --git a/uploader/templates/publications/create-publication.html b/uploader/templates/publications/create-publication.html
new file mode 100644
index 0000000..3f828a9
--- /dev/null
+++ b/uploader/templates/publications/create-publication.html
@@ -0,0 +1,191 @@
+{%extends "publications/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}View Publication{%endblock%}
+
+{%block pagetitle%}View Publication{%endblock%}
+
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <form id="frm-create-publication"
+        method="POST"
+        action="{{url_for('publications.create_publication', **request.args)}}"
+        class="form-horizontal">
+
+    <div class="row mb-3">
+      <label for="txt-pubmed-id" class="col-sm-2 col-form-label">
+        PubMed ID</label>
+      <div class="col-sm-10">
+        <div class="input-group">
+          <input type="text"
+                 id="txt-pubmed-id"
+                 name="pubmed-id"
+                 class="form-control"/>
+          <div class="input-group-text">
+            <button class="btn btn-outline-primary"
+                    id="btn-search-pubmed-id">search</button>
+          </div>
+        </div>
+        <span id="search-pubmed-id-error"
+              class="form-text text-muted text-danger visually-hidden">
+        </span>
+        <span class="form-text text-muted">This is the publication's ID on
+          <a href="https://pubmed.ncbi.nlm.nih.gov/"
+             title="Link to NCBI's PubMed service">NCBI's Pubmed Service</a>
+        </span>
+      </div>
+    </div>
+
+    <div class="row mb-3">
+      <label for="txt-publication-title" class="col-sm-2 col-form-label">
+        Title</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-publication-title"
+               name="publication-title"
+               class="form-control" />
+        <span class="form-text text-muted">Provide the publication's title here.</span>
+      </div>
+    </div>
+
+    <div class="row mb-3">
+      <label for="txt-publication-authors" class="col-sm-2 col-form-label">
+        Authors</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-publication-authors"
+               name="publication-authors"
+               required="required"
+               class="form-control" />
+        <span class="form-text text-muted">
+          A publication <strong>MUST</strong> have an author. You <em>must</em>
+          provide a value for the authors field.
+        </span>
+      </div>
+    </div>
+
+    <div class="row mb-3">
+      <label for="txt-publication-journal" class="col-sm-2 col-form-label">
+        Journal</label>
+      <div class="col-sm-10">
+        <input type="text"
+               id="txt-publication-journal"
+               name="publication-journal"
+               class="form-control" />
+        <span class="form-text text-muted">Provide the name journal where the
+          publication was done, here.</span>
+      </div>
+    </div>
+
+    <div class="row mb-3">
+      <label for="select-publication-month"
+             class="col-sm-2 col-form-label">
+        Month</label>
+      <div class="col-sm-4">
+        <select class="form-control"
+                id="select-publication-month"
+                name="publication-month">
+          <option value="">Select a month</option>
+          <option value="january">January</option>
+          <option value="february">February</option>
+          <option value="march">March</option>
+          <option value="april">April</option>
+          <option value="may">May</option>
+          <option value="june">June</option>
+          <option value="july">July</option>
+          <option value="august">August</option>
+          <option value="september">September</option>
+          <option value="october">October</option>
+          <option value="november">November</option>
+          <option value="december">December</option>
+        </select>
+        <span class="form-text text-muted">Month of publication</span>
+      </div>
+
+      <label for="txt-publication-year"
+             class="col-sm-2 col-form-label">
+        Year</label>
+      <div class="col-sm-4">
+        <input type="number"
+               id="txt-publication-year"
+               name="publication-year"
+               class="form-control"
+               min="1960" />
+        <span class="form-text text-muted">Year of publication</span>
+      </div>
+    </div>
+
+    <div class="row mb-3">
+      <label for="txt-publication-volume"
+             class="col-sm-2 col-form-label">
+        Volume</label>
+      <div class="col-sm-4">
+        <input type="text"
+               id="txt-publication-volume"
+               name="publication-volume"
+               class="form-control">
+        <span class="form-text text-muted">Journal volume</span>
+      </div>
+
+      <label for="txt-publication-pages"
+             class="col-sm-2 col-form-label">
+        Pages</label>
+      <div class="col-sm-4">
+        <input type="text"
+               id="txt-publication-pages"
+               name="publication-pages"
+               class="form-control" />
+        <span class="form-text text-muted">Journal pages for the publication</span>
+      </div>
+    </div>
+
+    <div class="row mb-3">
+      <label for="txt-abstract" class="col-sm-2 col-form-label">Abstract</label>
+      <div class="col-sm-10">
+        <textarea id="txt-publication-abstract"
+                  name="publication-abstract"
+                  class="form-control"
+                  rows="7"></textarea>
+      </div>
+    </div>
+
+    <div class="row mb-3">
+      <div class="col-sm-2"></div>
+      <div class="col-sm-8">
+        <input type="submit" class="btn btn-primary" value="Add" />
+        <input type="reset" class="btn btn-danger" />
+      </div>
+    </div>
+
+</form>
+</div>
+
+{%endblock%}
+
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/pubmed.js"></script>
+<script type="text/javascript">
+  $(function() {
+      $("#btn-search-pubmed-id").on("click", (event) => {
+          event.preventDefault();
+          var search_button = event.target;
+          var pubmed_id = $("#txt-pubmed-id").val().trim();
+          remove_class($("#txt-pubmed-id").parent(), "has-error");
+          if(pubmed_id == "") {
+              add_class($("#txt-pubmed-id").parent(), "has-error");
+              return false;
+          }
+
+          search_button.disabled = true;
+          // Fetch publication details
+          fetch_publication_details(pubmed_id,
+                                    [() => {search_button.disabled = false;}]);
+          return false;
+      });
+  });
+</script>
+{%endblock%}
diff --git a/uploader/templates/publications/index.html b/uploader/templates/publications/index.html
new file mode 100644
index 0000000..369812b
--- /dev/null
+++ b/uploader/templates/publications/index.html
@@ -0,0 +1,100 @@
+{%extends "publications/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}Publications{%endblock%}
+
+{%block pagetitle%}Publications{%endblock%}
+
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row" style="padding-bottom: 1em;">
+  <a href="{{url_for('publications.create_publication')}}"
+     class="btn btn-primary">
+    add new publication</a>
+</div>
+
+<div class="row">
+  <table id="tbl-list-publications" class="table compact stripe">
+    <thead>
+      <tr>
+        <th>#</th>
+        <th>PubMed ID</th>
+        <th>Title</th>
+        <th>Authors</th>
+      </tr>
+    </thead>
+
+    <tbody></tbody>
+  </table>
+</div>
+{%endblock%}
+
+
+{%block javascript%}
+<script type="text/javascript">
+  $(function() {
+      var publicationsDataTable = buildDataTable(
+          "#tbl-list-publications",
+          [],
+          [
+              {data: "index"},
+              {
+                  searchable: true,
+                  data: (pub) => {
+                  if(pub.PubMed_ID) {
+                      return `<a href="https://pubmed.ncbi.nlm.nih.gov/` +
+                          `${pub.PubMed_ID}/" target="_blank" ` +
+                          `title="Link to publication on NCBI.">` +
+                          `${pub.PubMed_ID}</a>`;
+                  }
+                  return "";
+                  }
+              },
+              {
+                  searchable: true,
+                  data: (pub) => {
+                  var title = "⸻";
+                  if(pub.Title) {
+                      title = pub.Title
+                  }
+                  return `<a href="/publications/view/${pub.Id}" ` +
+                          `target="_blank" ` +
+                          `title="Link to view publication details">` +
+                          `${title}</a>`;
+                  }
+              },
+              {
+                  searchable: true,
+                  data: (pub) => {
+                  authors = pub.Authors.split(",").map(
+                      (item) => {return item.trim();});
+                  if(authors.length > 1) {
+                      return authors[0] + ", et. al.";
+                  }
+                  return authors[0];
+                  }
+              }
+          ],
+          {
+              serverSide: true,
+              ajax: {
+                  url: "/publications/list",
+                  dataSrc: "publications"
+              },
+              scrollY: 700,
+              scroller: true,
+              scrollCollapse: true,
+              paging: true,
+              deferRender: true,
+              layout: {
+                  topStart: "info",
+                  topEnd: "search",
+                  bottomStart: "pageLength",
+                  bottomEnd: false
+              }
+          });
+  });
+</script>
+{%endblock%}
diff --git a/uploader/templates/publications/view-publication.html b/uploader/templates/publications/view-publication.html
new file mode 100644
index 0000000..388547a
--- /dev/null
+++ b/uploader/templates/publications/view-publication.html
@@ -0,0 +1,78 @@
+{%extends "publications/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}View Publication{%endblock%}
+
+{%block pagetitle%}View Publication{%endblock%}
+
+
+{%block contents%}
+{{flash_all_messages()}}
+
+<div class="row">
+  <table class="table">
+    <tr>
+      <th>PubMed</th>
+      <td>
+        {%if publication.PubMed_ID%}
+        <a href="https://pubmed.ncbi.nlm.nih.gov/{{publication.PubMed_ID}}/"
+           target="_blank">{{publication.PubMed_ID}}</a>
+        {%else%}
+        —
+        {%endif%}
+      </td>
+    </tr>
+    <tr>
+      <th>Title</th>
+      <td>{{publication.Title or "—"}}</td>
+    </tr>
+    <tr>
+      <th>Authors</th>
+      <td>{{publication.Authors or "—"}}</td>
+    </tr>
+    <tr>
+      <th>Journal</th>
+      <td>{{publication.Journal or "—"}}</td>
+    </tr>
+    <tr>
+      <th>Published</th>
+      <td>{{publication.Month or ""}} {{publication.Year or "—"}}</td>
+    </tr>
+    <tr>
+      <th>Volume</th>
+      <td>{{publication.Volume or "—"}}</td>
+    </tr>
+    <tr>
+      <th>Pages</th>
+      <td>{{publication.Pages or "—"}}</td>
+    </tr>
+    <tr>
+      <th>Abstract</th>
+      <td>
+        {%for line in (publication.Abstract or "—").replace("\r\n", "<br />").replace("\n", "<br />").split("<br />")%}
+        <p>{{line}}</p>
+        {%endfor%}
+      </td>
+    </tr>
+  </table>
+</div>
+
+<div class="row">
+  <form id="frm-edit-delete-publication" method="POST" action="#">
+    <input type="hidden" name="publication_id" value="{{publication.Id}}" />
+    <div class="form-group">
+      <input type="submit" value="edit" class="btn btn-primary not-implemented" />
+      {%if linked_phenotypes | length == 0%}
+      <input type="submit" value="delete" class="btn btn-danger not-implemented" />
+      {%endif%}
+    </div>
+  </form>
+</div>
+{%endblock%}
+
+
+{%block javascript%}
+<script type="text/javascript">
+  $(function() {});
+</script>
+{%endblock%}
diff --git a/uploader/templates/rqtl2/create-geno-dataset-success.html b/uploader/templates/rqtl2/create-geno-dataset-success.html
deleted file mode 100644
index bb6d63d..0000000
--- a/uploader/templates/rqtl2/create-geno-dataset-success.html
+++ /dev/null
@@ -1,55 +0,0 @@
-{%extends "base.html"%}
-{%from "flash_messages.html" import flash_messages%}
-
-{%block title%}Upload R/qtl2 Bundle{%endblock%}
-
-{%block contents%}
-<h2 class="heading">Select Genotypes Dataset</h2>
-
-<div class="explainer">
-  <p>You successfully created the genotype dataset with the following
-    information.
-    <dl>
-      <dt>ID</dt>
-      <dd>{{geno_dataset.id}}</dd>
-
-      <dt>Name</dt>
-      <dd>{{geno_dataset.name}}</dd>
-
-      <dt>Full Name</dt>
-      <dd>{{geno_dataset.fname}}</dd>
-
-      <dt>Short Name</dt>
-      <dd>{{geno_dataset.sname}}</dd>
-
-      <dt>Created On</dt>
-      <dd>{{geno_dataset.today}}</dd>
-
-      <dt>Public?</dt>
-      <dd>{%if geno_dataset.public == 0%}No{%else%}Yes{%endif%}</dd>
-    </dl>
-  </p>
-</div>
-
-<div class="row">
-  <form id="frm-upload-rqtl2-bundle"
-        action="{{url_for('expression-data.rqtl2.select_dataset_info',
-	        species_id=species.SpeciesId,
-	        population_id=population.InbredSetId)}}"
-        method="POST"
-        enctype="multipart/form-data">
-    <legend class="heading">select from existing genotype datasets</legend>
-
-    <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
-    <input type="hidden" name="population_id"
-	   value="{{population.InbredSetId}}" />
-    <input type="hidden" name="rqtl2_bundle_file"
-	   value="{{rqtl2_bundle_file}}" />
-    <input type="hidden" name="geno-dataset-id"
-	   value="{{geno_dataset.id}}" />
-
-    <button type="submit" class="btn btn-primary">continue</button>
-  </form>
-</div>
-
-{%endblock%}
diff --git a/uploader/templates/rqtl2/create-probe-dataset-success.html b/uploader/templates/rqtl2/create-probe-dataset-success.html
deleted file mode 100644
index 03b75c7..0000000
--- a/uploader/templates/rqtl2/create-probe-dataset-success.html
+++ /dev/null
@@ -1,59 +0,0 @@
-{%extends "base.html"%}
-{%from "flash_messages.html" import flash_messages%}
-
-{%block title%}Upload R/qtl2 Bundle{%endblock%}
-
-{%block contents%}
-<h2 class="heading">Create ProbeSet Dataset</h2>
-
-<div class="row">
-  <p>You successfully created the ProbeSet dataset with the following
-    information.
-    <dl>
-      <dt>Averaging Method</dt>
-      <dd>{{avgmethod.Name}}</dd>
-
-      <dt>ID</dt>
-      <dd>{{dataset.datasetid}}</dd>
-
-      <dt>Name</dt>
-      <dd>{{dataset.name2}}</dd>
-
-      <dt>Full Name</dt>
-      <dd>{{dataset.fname}}</dd>
-
-      <dt>Short Name</dt>
-      <dd>{{dataset.sname}}</dd>
-
-      <dt>Created On</dt>
-      <dd>{{dataset.today}}</dd>
-
-      <dt>DataScale</dt>
-      <dd>{{dataset.datascale}}</dd>
-    </dl>
-  </p>
-</div>
-
-<div class="row">
-  <form id="frm-upload-rqtl2-bundle"
-        action="{{url_for('expression-data.rqtl2.select_dataset_info',
-	        species_id=species.SpeciesId,
-	        population_id=population.InbredSetId)}}"
-        method="POST"
-        enctype="multipart/form-data">
-    <legend class="heading">Create ProbeSet dataset</legend>
-
-    <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
-    <input type="hidden" name="population_id"
-	   value="{{population.InbredSetId}}" />
-    <input type="hidden" name="rqtl2_bundle_file" value="{{rqtl2_bundle_file}}" />
-    <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
-    <input type="hidden" name="tissueid" value="{{tissue.Id}}" />
-    <input type="hidden" name="probe-study-id" value="{{study.Id}}" />
-    <input type="hidden" name="probe-dataset-id" value="{{dataset.datasetid}}" />
-
-    <button type="submit" class="btn btn-primary">continue</button>
-  </form>
-</div>
-
-{%endblock%}
diff --git a/uploader/templates/rqtl2/create-probe-study-success.html b/uploader/templates/rqtl2/create-probe-study-success.html
deleted file mode 100644
index e293f6f..0000000
--- a/uploader/templates/rqtl2/create-probe-study-success.html
+++ /dev/null
@@ -1,49 +0,0 @@
-{%extends "base.html"%}
-{%from "flash_messages.html" import flash_messages%}
-
-{%block title%}Upload R/qtl2 Bundle{%endblock%}
-
-{%block contents%}
-<h2 class="heading">Create ProbeSet Study</h2>
-
-<div class="row">
-  <p>You successfully created the ProbeSet study with the following
-    information.
-    <dl>
-      <dt>ID</dt>
-      <dd>{{study.id}}</dd>
-
-      <dt>Name</dt>
-      <dd>{{study.name}}</dd>
-
-      <dt>Full Name</dt>
-      <dd>{{study.fname}}</dd>
-
-      <dt>Short Name</dt>
-      <dd>{{study.sname}}</dd>
-
-      <dt>Created On</dt>
-      <dd>{{study.today}}</dd>
-    </dl>
-  </p>
-
-  <form id="frm-upload-rqtl2-bundle"
-        action="{{url_for('expression-data.rqtl2.select_dataset_info',
-	        species_id=species.SpeciesId,
-	        population_id=population.InbredSetId)}}"
-        method="POST"
-        enctype="multipart/form-data">
-    <legend class="heading">Create ProbeSet study</legend>
-
-    <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
-    <input type="hidden" name="population_id"
-	   value="{{population.InbredSetId}}" />
-    <input type="hidden" name="rqtl2_bundle_file" value="{{rqtl2_bundle_file}}" />
-    <input type="hidden" name="geno-dataset-id" value="{{geno_dataset.Id}}" />
-    <input type="hidden" name="probe-study-id" value="{{study.studyid}}" />
-
-    <button type="submit" class="btn btn-primary">continue</button>
-  </form>
-</div>
-
-{%endblock%}
diff --git a/uploader/templates/rqtl2/index.html b/uploader/templates/rqtl2/index.html
deleted file mode 100644
index 8ce13bf..0000000
--- a/uploader/templates/rqtl2/index.html
+++ /dev/null
@@ -1,36 +0,0 @@
-{%extends "base.html"%}
-{%from "flash_messages.html" import flash_messages%}
-
-{%block title%}Data Upload{%endblock%}
-
-{%block contents%}
-<h1 class="heading">R/qtl2 data upload</h1>
-
-<h2>R/qtl2 Upload</h2>
-
-<form method="POST" action="{{url_for('expression-data.rqtl2.select_species')}}"
-      id="frm-rqtl2-upload">
-  <legend class="heading">upload R/qtl2 bundle</legend>
-  {{flash_messages("error-rqtl2")}}
-
-  <div class="form-group">
-    <label for="select:species" class="form-label">Species</label>
-    <select id="select:species"
-            name="species_id"
-            required="required"
-            class="form-control">
-      <option value="">Select species</option>
-      {%for spec in species%}
-      <option value="{{spec.SpeciesId}}">{{spec.MenuName}}</option>
-      {%endfor%}
-    </select>
-    <small class="form-text text-muted">
-      Data that you upload to the system should belong to a know species.
-      Here you can select the species that you wish to upload data for.
-    </small>
-  </div>
-
-  <button type="submit" class="btn btn-primary" />submit</button>
-</form>
-
-{%endblock%}
diff --git a/uploader/templates/rqtl2/select-geno-dataset.html b/uploader/templates/rqtl2/select-geno-dataset.html
deleted file mode 100644
index 1db51e0..0000000
--- a/uploader/templates/rqtl2/select-geno-dataset.html
+++ /dev/null
@@ -1,144 +0,0 @@
-{%extends "base.html"%}
-{%from "flash_messages.html" import flash_messages%}
-
-{%block title%}Upload R/qtl2 Bundle{%endblock%}
-
-{%block contents%}
-<h2 class="heading">Select Genotypes Dataset</h2>
-
-<div class="row">
-  <p>Your R/qtl2 files bundle contains a "geno" specification. You will
-    therefore need to select from one of the existing Genotype datasets or
-    create a new one.</p>
-  <p>This is the dataset where your data will be organised under.</p>
-</div>
-
-<div class="row">
-  <form id="frm-upload-rqtl2-bundle"
-        action="{{url_for('expression-data.rqtl2.select_geno_dataset',
-	        species_id=species.SpeciesId,
-	        population_id=population.InbredSetId)}}"
-        method="POST"
-        enctype="multipart/form-data">
-    <legend class="heading">select from existing genotype datasets</legend>
-
-    <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
-    <input type="hidden" name="population_id"
-	   value="{{population.InbredSetId}}" />
-    <input type="hidden" name="rqtl2_bundle_file"
-	   value="{{rqtl2_bundle_file}}" />
-
-    {{flash_messages("error-rqtl2-select-geno-dataset")}}
-
-    <div class="form-group">
-      <legend>Datasets</legend>
-      <label for="select:geno-datasets" class="form-label">Dataset</label>
-      <select id="select:geno-datasets"
-	      name="geno-dataset-id"
-	      required="required"
-	      {%if datasets | length == 0%}
-	      disabled="disabled"
-	      {%endif%}
-              class="form-control"
-              aria-describedby="help-geno-dataset-select-dataset">
-        <option value="">Select dataset</option>
-        {%for dset in datasets%}
-        <option value="{{dset['Id']}}">{{dset["Name"]}} ({{dset["FullName"]}})</option>
-        {%endfor%}
-      </select>
-      <span id="help-geno-dataset-select-dataset" class="form-text text-muted">
-        Select from the existing genotype datasets for species
-        {{species.SpeciesName}} ({{species.FullName}}).
-      </span>
-    </div>
-
-    <button type="submit" class="btn btn-primary">select dataset</button>
-  </form>
-</div>
-
-<div class="row">
-  <p style="color:#FE3535; padding-left:20em; font-weight:bolder;">OR</p>
-</div>
-
-<div class="row">
-  <form id="frm-upload-rqtl2-bundle"
-        action="{{url_for('expression-data.rqtl2.create_geno_dataset',
-	        species_id=species.SpeciesId,
-	        population_id=population.InbredSetId)}}"
-        method="POST"
-        enctype="multipart/form-data">
-    <legend class="heading">create a new genotype dataset</legend>
-
-    <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
-    <input type="hidden" name="population_id"
-	   value="{{population.InbredSetId}}" />
-    <input type="hidden" name="rqtl2_bundle_file"
-	   value="{{rqtl2_bundle_file}}" />
-
-    {{flash_messages("error-rqtl2-create-geno-dataset")}}
-
-    <div class="form-group">
-      <label for="txt:dataset-name" class="form-label">Name</label>
-      <input type="text"
-	     id="txt:dataset-name"
-	     name="dataset-name"
-	     maxlength="100"
-	     required="required"
-             class="form-control"
-             aria-describedby="help-geno-dataset-name" />
-      <span id="help-geno-dataset-name" class="form-text text-muted">
-        Provide the new name for the genotype dataset, e.g. "BXDGeno"
-      </span>
-    </div>
-
-    <div class="form-group">
-      <label for="txt:dataset-fullname" class="form-label">Full Name</label>
-      <input type="text"
-	     id="txt:dataset-fullname"
-	     name="dataset-fullname"
-	     required="required"
-	     maxlength="100"
-             class="form-control"
-             aria-describedby="help-geno-dataset-fullname" />
-
-      <span id="help-geno-dataset-fullname" class="form-text text-muted">
-        Provide a longer name that better describes the genotype dataset, e.g.
-        "BXD Genotypes"
-      </span>
-    </div>
-
-    <div class="form-group">
-      <label for="txt:dataset-shortname" class="form-label">Short Name</label>
-      <input type="text"
-	     id="txt:dataset-shortname"
-	     name="dataset-shortname"
-	     maxlength="100"
-             class="form-control"
-             aria-describedby="help-geno-dataset-shortname" />
-
-      <span id="help-geno-dataset-shortname" class="form-text text-muted">
-        Provide a short name for the genotype dataset. This is optional. If not
-        provided, we'll default to the same value as the "Name" above.
-      </span>
-    </div>
-
-    <div class="form-group">
-      <input type="checkbox"
-	     id="chk:dataset-public"
-	     name="dataset-public"
-	     checked="checked"
-             class="form-check"
-             aria-describedby="help-geno-datasent-public" />
-      <label for="chk:dataset-public" class="form-check-label">Public?</label>
-
-      <span id="help-geno-dataset-public" class="form-text text-muted">
-        Specify whether the dataset will be available publicly. Check to make the
-        dataset publicly available and uncheck to limit who can access the dataset.
-      </span>
-    </div>
-
-    <button type="submit" class="btn btn-primary">create new dataset</button>
-  </form>
-</div>
-
-{%endblock%}
diff --git a/uploader/templates/rqtl2/select-population.html b/uploader/templates/rqtl2/select-population.html
deleted file mode 100644
index 7d27303..0000000
--- a/uploader/templates/rqtl2/select-population.html
+++ /dev/null
@@ -1,136 +0,0 @@
-{%extends "base.html"%}
-{%from "flash_messages.html" import flash_messages%}
-
-{%block title%}Select Grouping/Population{%endblock%}
-
-{%block contents%}
-<h1 class="heading">Select grouping/population</h1>
-
-<div class="explainer">
-  <p>The data is organised in a hierarchical form, beginning with
-    <em>species</em> at the very top. Under <em>species</em> the data is
-    organised by <em>population</em>, sometimes referred to as <em>grouping</em>.
-    (In some really old documents/systems, you might see this referred to as
-    <em>InbredSet</em>.)</p>
-  <p>In this section, you get to define what population your data is to be
-    organised by.</p>
-</div>
-
-<form method="POST"
-      action="{{url_for('expression-data.rqtl2.select_population', species_id=species.SpeciesId)}}">
-  <legend class="heading">select grouping/population</legend>
-  {{flash_messages("error-select-population")}}
-
-  <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
-
-  <div class="form-group">
-    <label for="select:inbredset" class="form-label">population</label>
-    <select id="select:inbredset"
-	    name="inbredset_id"
-	    required="required"
-	    class="form-control">
-      <option value="">Select a grouping/population</option>
-      {%for pop in populations%}
-      <option value="{{pop.InbredSetId}}">
-	{{pop.InbredSetName}} ({{pop.FullName}})</option>
-      {%endfor%}
-    </select>
-    <span class="form-text text-muted">If you are adding data to an already existing
-      population, simply pick the population from this drop-down selector. If
-      you cannot find your population from this list, try the form below to
-      create a new one..</span>
-  </div>
-
-  <button type="submit" class="btn btn-primary" />select population</button>
-</form>
-
-<p style="color:#FE3535; padding-left:20em; font-weight:bolder;">OR</p>
-
-<form method="POST"
-      action="{{url_for('expression-data.rqtl2.create_population', species_id=species.SpeciesId)}}">
-  <legend class="heading">create new grouping/population</legend>
-  {{flash_messages("error-create-population")}}
-
-  <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
-
-  <div class="form-group">
-    <legend class="heading">mandatory</legend>
-
-    <div class="form-group">
-      <label for="txt:inbredset-name" class="form-label">name</label>
-      <input id="txt:inbredset-name"
-	     name="inbredset_name"
-	     type="text"
-	     required="required"
-	     maxlength="30"
-	     placeholder="Enter grouping/population name"
-	     class="form-control" />
-      <span class="form-text text-muted">This is a short name that identifies the
-        population. Useful for menus, and quick scanning.</span>
-    </div>
-
-    <div class="form-group">
-      <label for="txt:" class="form-label">full name</label>
-      <input id="txt:inbredset-fullname"
-	     name="inbredset_fullname"
-	     type="text"
-	     required="required"
-	     maxlength="100"
-	     placeholder="Enter the grouping/population's full name"
-	     class="form-control" />
-      <span class="form-text text-muted">This can be the same as the name above, or can
-        be longer. Useful for documentation, and human communication.</span>
-    </div>
-  </div>
-
-  <div class="form-group">
-    <legend class="heading">optional</legend>
-
-    <div class="form-group">
-      <label for="num:public" class="form-label">public?</label>
-      <select id="num:public"
-	      name="public"
-	      class="form-control">
-        <option value="0">0 - Only accessible to authorised users</option>
-        <option value="1">1 - Publicly accessible to all users</option>
-        <option value="2" selected>
-	  2 - Publicly accessible to all users</option>
-      </select>
-      <span class="form-text text-muted">This determines whether the
-        population/grouping will appear on the menus for users.</span>
-    </div>
-
-    <div class="form-group">
-      <label for="txt:inbredset-family" class="form-label">family</label>
-      <input id="txt:inbredset-family"
-	     name="inbredset_family"
-	     type="text"
-	     placeholder="I am not sure what this is about."
-	     class="form-control" />
-      <span class="form-text text-muted">I do not currently know what this is about.
-        This is a failure on my part to figure out what this is and provide a
-        useful description. Please feel free to remind me.</span>
-    </div>
-
-    <div class="form-group">
-    <label for="txtarea:" class="form-label">Description</label>
-    <textarea id="txtarea:description"
-	      name="description"
-	      rows="5"
-	      placeholder="Enter a description of this grouping/population"
-	      class="form-control"></textarea>
-    <span class="form-text text-muted">
-      A long-form description of what the population consists of. Useful for
-      humans.</span>
-    </div>
-  </div>
-
-  <button type="submit" class="btn btn-primary" />
-  create grouping/population</button>
-</form>
-
-{%endblock%}
-
-
-{%block javascript%}
-{%endblock%}
diff --git a/uploader/templates/samples/index.html b/uploader/templates/samples/index.html
index ee4a63e..ee98734 100644
--- a/uploader/templates/samples/index.html
+++ b/uploader/templates/samples/index.html
@@ -17,3 +17,7 @@
   {{select_species_form(url_for("species.populations.samples.index"), species)}}
 </div>
 {%endblock%}
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/species.js"></script>
+{%endblock%}
diff --git a/uploader/templates/samples/list-samples.html b/uploader/templates/samples/list-samples.html
index 13e5cec..aed27c3 100644
--- a/uploader/templates/samples/list-samples.html
+++ b/uploader/templates/samples/list-samples.html
@@ -29,6 +29,19 @@
   </p>
 </div>
 
+<div class="row">
+  <p>
+    <a href="{{url_for('species.populations.samples.upload_samples',
+             species_id=species.SpeciesId,
+             population_id=population.Id)}}"
+       title="Add samples for population '{{population.FullName}}' from species
+              '{{species.FullName}}'."
+       class="btn btn-primary">
+      add samples
+    </a>
+  </p>
+</div>
+
 {%if samples | length > 0%}
 <div class="row">
   <p>
@@ -73,7 +86,7 @@
   <table class="table">
     <thead>
       <tr>
-        <th>#</th>
+        <th></th>
         <th>Name</th>
         <th>Auxilliary Name</th>
         <th>Symbol</th>
@@ -96,32 +109,17 @@
 
   <p>
     <a href="#"
-       title="Add samples for population '{{population.FullName}}' from species
+       title="Delete samples from population '{{population.FullName}}' from species
               '{{species.FullName}}'."
-       class="btn btn-danger">
+       class="btn btn-danger not-implemented">
       delete all samples
     </a>
   </p>
 </div>
-
 {%else%}
-
 <div class="row">
-  <p>
-    There are no samples entered for this population. Do please go ahead and add
-    the samples for this population by clicking on the button below.
-  </p>
-
-  <p>
-    <a href="{{url_for('species.populations.samples.upload_samples',
-             species_id=species.SpeciesId,
-             population_id=population.Id)}}"
-       title="Add samples for population '{{population.FullName}}' from species
-              '{{species.FullName}}'."
-       class="btn btn-primary">
-      add samples
-    </a>
-  </p>
+  <p>There are no samples entered for this population. Click the "Add Samples"
+    button above, to add some new samples.</p>
 </div>
 {%endif%}
 
diff --git a/uploader/templates/samples/select-population.html b/uploader/templates/samples/select-population.html
index f437780..1cc7573 100644
--- a/uploader/templates/samples/select-population.html
+++ b/uploader/templates/samples/select-population.html
@@ -12,28 +12,15 @@
 {{flash_all_messages()}}
 
 <div class="row">
-  <p>You have selected "{{species.FullName}}" as the species that your data relates to.</p>
-  <p>Next, we need information regarding the population your data relates to. Do please select the population from the existing ones below</p>
-</div>
-
-<div class="row">
   {{select_population_form(
-  url_for("species.populations.samples.select_population", species_id=species.SpeciesId),
-  populations)}}
-</div>
-
-<div class="row">
-  <p>
-    If you cannot find the population your data relates to in the drop-down
-    above, you might want to
-    <a href="{{url_for('species.populations.create_population',
-             species_id=species.SpeciesId)}}"
-       title="Create a new population for species '{{species.FullName}},">
-      add a new population to GeneNetwork</a>
-    instead.
+  url_for("species.populations.samples.select_population", species_id=species.SpeciesId), species, populations)}}
 </div>
 {%endblock%}
 
 {%block sidebarcontents%}
 {{display_species_card(species)}}
 {%endblock%}
+
+{%block javascript%}
+<script type="text/javascript" src="/static/js/populations.js"></script>
+{%endblock%}
diff --git a/uploader/templates/samples/upload-failure.html b/uploader/templates/samples/upload-failure.html
index 458ab55..2cf8053 100644
--- a/uploader/templates/samples/upload-failure.html
+++ b/uploader/templates/samples/upload-failure.html
@@ -15,7 +15,7 @@
 
 <h3>Debugging Information</h3>
 <ul>
-  <li><strong>job id</strong>: {{job.job_id}}</li>
+  <li><strong>job id</strong>: {{job.jobid}}</li>
   <li><strong>status</strong>: {{job.status}}</li>
   <li><strong>job type</strong>: {{job["job-type"]}}</li>
 </ul>
diff --git a/uploader/templates/samples/upload-samples.html b/uploader/templates/samples/upload-samples.html
index 25d3290..6422094 100644
--- a/uploader/templates/samples/upload-samples.html
+++ b/uploader/templates/samples/upload-samples.html
@@ -66,7 +66,7 @@
     <div class="form-group">
       <label for="file-samples" class="form-label">select file</label>
       <input type="file" name="samples_file" id="file:samples"
-	     accept="text/csv, text/tab-separated-values"
+	     accept="text/csv, text/tab-separated-values, text/plain"
 	     class="form-control" />
     </div>
 
diff --git a/uploader/templates/select_species.html b/uploader/templates/select_species.html
deleted file mode 100644
index 1642401..0000000
--- a/uploader/templates/select_species.html
+++ /dev/null
@@ -1,92 +0,0 @@
-{%extends "base.html"%}
-{%from "flash_messages.html" import flash_messages%}
-{%from "upload_progress_indicator.html" import upload_progress_indicator%}
-
-{%block title%}expression data: select species{%endblock%}
-
-{%block contents%}
-{{upload_progress_indicator()}}
-
-<h2 class="heading">expression data: select species</h2>
-
-<div class="row">
-  <form action="{{url_for('expression-data.index.upload_file')}}"
-        method="POST"
-        enctype="multipart/form-data"
-        id="frm-upload-expression-data">
-    <legend class="heading">upload expression data</legend>
-    {{flash_messages("error-expr-data")}}
-
-    <div class="form-group">
-      <label for="select_species01" class="form-label">Species</label>
-      <select id="select_species01"
-	      name="speciesid"
-	      required="required"
-              class="form-control">
-        <option value="">Select species</option>
-        {%for aspecies in species%}
-        <option value="{{aspecies.SpeciesId}}">{{aspecies.MenuName}}</option>
-        {%endfor%}
-      </select>
-    </div>
-
-    <div class="form-group">
-      <legend class="heading">file type</legend>
-
-      <div class="form-check">
-        <input type="radio" name="filetype" value="average" id="filetype_average"
-	       required="required" class="form-check-input" />
-        <label for="filetype_average" class="form-check-label">average</label>
-      </div>
-
-      <div class="form-check">
-        <input type="radio" name="filetype" value="standard-error"
-	       id="filetype_standard_error" required="required"
-	       class="form-check-input" />
-        <label for="filetype_standard_error" class="form-check-label">
-          standard error
-        </label>
-      </div>
-    </div>
-
-    <div class="form-group">
-      <span id="no-file-error" class="alert-danger" style="display: none;">
-        No file selected
-      </span>
-      <label for="file_upload" class="form-label">select file</label>
-      <input type="file" name="qc_text_file" id="file_upload"
-	     accept="text/plain, text/tab-separated-values, application/zip"
-	     class="form-control"/>
-    </div>
-
-    <button type="submit"
-            class="btn btn-primary"
-            data-toggle="modal"
-            data-target="#upload-progress-indicator">upload file</button>
-  </form>
-</div>
-{%endblock%}
-
-
-{%block javascript%}
-<script type="text/javascript" src="static/js/upload_progress.js"></script>
-<script type="text/javascript">
-  function setup_formdata(form) {
-      var formdata = new FormData();
-      formdata.append(
-	  "speciesid",
-	  form.querySelector("#select_species01").value)
-      formdata.append(
-	  "qc_text_file",
-	  form.querySelector("input[type='file']").files[0]);
-      formdata.append(
-	  "filetype",
-	  selected_filetype(
-	      Array.from(form.querySelectorAll("input[type='radio']"))));
-      return formdata;
-  }
-
-  setup_upload_handlers(
-      "frm-upload-expression-data", make_data_uploader(setup_formdata));
-</script>
-{%endblock%}
diff --git a/uploader/templates/species/base.html b/uploader/templates/species/base.html
index 04391db..f64f72b 100644
--- a/uploader/templates/species/base.html
+++ b/uploader/templates/species/base.html
@@ -6,7 +6,12 @@
     {%else%}
     class="breadcrumb-item"
     {%endif%}>
+  {%if species is mapping%}
+  <a href="{{url_for('species.view_species', species_id=species.SpeciesId)}}">
+    {{species.Name}}</a>
+  {%else%}
   <a href="{{url_for('species.list_species')}}">Species</a>
+  {%endif%}
 </li>
 {%block lvl2_breadcrumbs%}{%endblock%}
 {%endblock%}
diff --git a/uploader/templates/species/create-species.html b/uploader/templates/species/create-species.html
index 0d0bedf..138dbaa 100644
--- a/uploader/templates/species/create-species.html
+++ b/uploader/templates/species/create-species.html
@@ -19,72 +19,88 @@
 <div class="row">
   <form id="frm-create-species"
         method="POST"
-        action="{{url_for('species.create_species')}}">
+        action="{{url_for('species.create_species', return_to=return_to)}}"
+        class="form-horizontal">
     <legend>Create Species</legend>
 
     {{flash_all_messages()}}
 
+    <input type="hidden" name="return_to" value="{{return_to}}">
+
     <div class="form-group">
-      <label for="txt-taxonomy-id" class="form-label">
+      <label for="txt-taxonomy-id" class="control-label col-sm-2">
         Taxonomy ID</label>
-      <div class="input-group">
-        <input id="txt-taxonomy-id"
-               name="species_taxonomy_id"
-               type="text"
-               class="form-control" />
-        <span class="input-group-btn">
-          <button id="btn-search-taxonid" class="btn btn-info">Search</button>
-        </span>
+      <div class="col-sm-10">
+        <div class="input-group">
+          <input id="txt-taxonomy-id"
+                 name="species_taxonomy_id"
+                 type="text"
+                 class="form-control" />
+          <span class="input-group-btn">
+            <button id="btn-search-taxonid" class="btn btn-info">Search</button>
+          </span>
+        </div>
+        <small class="form-text text-small text-muted">
+          Use
+          <a href="https://www.ncbi.nlm.nih.gov/Taxonomy/taxonomyhome.html/"
+             title="NCBI's Taxonomy Browser homepage"
+             target="_blank">
+            NCBI's Taxonomy Browser homepage</a> to search for the species you
+          want. If the species exists on NCBI, they will have a Taxonomy ID. Copy
+          that Taxonomy ID to this field, and click "Search" to auto-fill the
+          details.<br />
+          This field is optional.</small>
       </div>
-      <small class="form-text text-small text-muted">Provide the taxonomy ID for
-        your species that can be used to link to external sites like NCBI. Enter
-        the taxonomy ID and click "Search" to auto-fill the form with data.
-        <br />
-        While it is recommended to provide a value for this field, doing so is
-        optional.
-      </small>
     </div>
 
     <div class="form-group">
-      <label for="txt-species-name" class="form-label">Common Name</label>
-      <input id="txt-species-name"
-             name="common_name"
-             type="text"
-             class="form-control"
-             required="required" />
-      <small class="form-text text-muted">Provide the common, possibly
-        non-scientific name for the species here, e.g. Human, Mouse, etc.</small>
+      <label for="txt-species-name" class="control-label col-sm-2">Common Name</label>
+      <div class="col-sm-10">
+        <input id="txt-species-name"
+               name="common_name"
+               type="text"
+               class="form-control"
+               required="required" />
+        <small class="form-text text-muted">This is the day-to-day term used by
+          laymen, e.g. Mouse (instead of Mus musculus), round worm (instead of
+          Ascaris lumbricoides), etc.<br />
+          For species without this, just enter the scientific name.
+        </small>
+      </div>
     </div>
 
     <div class="form-group">
-      <label for="txt-species-scientific" class="form-label">
+      <label for="txt-species-scientific" class="control-label col-sm-2">
         Scientific Name</label>
-      <input id="txt-species-scientific"
-             name="scientific_name"
-             type="text"
-             class="form-control"
-             required="required" />
-      <small class="form-text text-muted">Provide the scientific name for the
-        species you are creating, e.g. Homo sapiens, Mus musculus, etc.</small>
+      <div class="col-sm-10">
+        <input id="txt-species-scientific"
+               name="scientific_name"
+               type="text"
+               class="form-control"
+               required="required" />
+        <small class="form-text text-muted">This is the scientific name for the
+          species e.g. Homo sapiens, Mus musculus, etc.</small>
+      </div>
     </div>
 
     <div class="form-group">
-      <label for="select-species-family" class="form-label">Family</label>
-      <select id="select-species-family"
-              name="species_family"
-              required="required"
-              class="form-control">
-        <option value="">Please select a grouping</option>
-        {%for family in families%}
-        <option value="{{family}}">{{family}}</option>
-        {%endfor%}
-      </select>
-      <small class="form-text text-muted">
-        This is a generic grouping for the species that determines under which
-        grouping the species appears in the GeneNetwork menus</small>
+      <label for="select-species-family" class="control-label col-sm-2">Family</label>
+      <div class="col-sm-10">
+        <select id="select-species-family"
+                name="species_family"
+                required="required"
+                class="form-control">
+          <option value="ungrouped">I do not know what to pick</option>
+          {%for family in families%}
+          <option value="{{family}}">{{family}}</option>
+          {%endfor%}
+        </select>
+        <small class="form-text text-muted">
+          This is a rough grouping of the species.</small>
+      </div>
     </div>
 
-    <div class="form-group">
+    <div class="col-sm-offset-2 col-sm-10">
       <input type="submit"
              value="create new species"
              class="btn btn-primary" />
@@ -113,7 +129,7 @@
               }
               msg = (
                   "Request to '${uri}' failed with message '${textStatus}'. "
-                  + "Please try again later, or fill the details manually.");
+                      + "Please try again later, or fill the details manually.");
               alert(msg);
               console.error(msg, data, textStatus);
               return false;
diff --git a/uploader/templates/species/list-species.html b/uploader/templates/species/list-species.html
index 85c9d40..64084b0 100644
--- a/uploader/templates/species/list-species.html
+++ b/uploader/templates/species/list-species.html
@@ -29,7 +29,7 @@
     <caption>Available Species</caption>
     <thead>
       <tr>
-        <th>#</td>
+        <th></td>
         <th title="A common, layman's name for the species.">Common Name</th>
         <th title="The scientific name for the species">Organism Name</th>
         <th title="An identifier for the species in the NCBI taxonomy database">
diff --git a/uploader/templates/species/macro-display-species-card.html b/uploader/templates/species/macro-display-species-card.html
index 857c0f0..166c7b9 100644
--- a/uploader/templates/species/macro-display-species-card.html
+++ b/uploader/templates/species/macro-display-species-card.html
@@ -3,13 +3,19 @@
   <div class="card-body">
     <h5 class="card-title">Species</h5>
     <div class="card-text">
-      <dl>
-        <dt>Common Name</dt>
-        <dd>{{species.SpeciesName}}</dd>
+      <table class="table">
+        <tbody>
+          <tr>
+            <td>Common Name</td>
+            <td>{{species.SpeciesName}}</td>
+          </tr>
 
-        <dt>Scientific Name</dt>
-        <dd>{{species.FullName}}</dd>
-      </dl>
+          <tr>
+            <td>Scientific Name</td>
+            <td>{{species.FullName}}</td>
+          </tr>
+        </tbody>
+      </table>
     </div>
   </div>
 </div>
diff --git a/uploader/templates/species/macro-select-species.html b/uploader/templates/species/macro-select-species.html
index dd086c0..3714ae4 100644
--- a/uploader/templates/species/macro-select-species.html
+++ b/uploader/templates/species/macro-select-species.html
@@ -1,36 +1,59 @@
+{%from "macro-step-indicator.html" import step_indicator%}
+
 {%macro select_species_form(form_action, species)%}
-{%if species | length > 0%}
-<form method="GET" action="{{form_action}}">
-  <div class="form-group">
-    <label for="select-species" class="form-label">Species</label>
-    <select id="select-species"
-            name="species_id"
-            class="form-control"
-            required="required">
-      <option value="">Select Species</option>
-      {%for group in species%}
-      {{group}}
-      <optgroup {%if group[0][1] is not none%}
-                label="{{group[0][1].capitalize()}}"
-                {%else%}
-                label="Undefined"
-                {%endif%}>
-        {%for aspecies in group[1]%}
-        <option value="{{aspecies.SpeciesId}}">{{aspecies.MenuName}}</option>
-        {%endfor%}
-      </optgroup>
-      {%endfor%}
-    </select>
+<form method="GET" action="{{form_action}}" class="form-horizontal">
+
+  <h2>{{step_indicator("1")}} What species do you want to work with?</h2>
+
+  {%if species | length != 0%}
+
+  <p class="form-text">Search for, and select the species from the table below
+    and click "Continue"</p>
+
+  <div class="radio">
+    <label for="rdo-cant-find-species"
+           style="font-weight: 1;">
+      <input id="rdo-cant-find-species" type="radio" name="species_id"
+             value="CREATE-SPECIES" />
+      I could not find the species I want (create it).
+    </label>
   </div>
 
-  <div class="form-group">
-    <input type="submit" value="Select" class="btn btn-primary" />
+  <div class="col-sm-offset-10 col-sm-2">
+    <input type="submit"
+           class="btn btn-primary"
+           value="continue" />
   </div>
+
+  <div style="margin-top:3em;">
+    <table id="tbl-select-species" class="table compact stripe"
+           data-species-list='{{species | tojson}}'>
+      <div class="">
+        <thead>
+          <tr>
+            <th></th>
+            <th>Species Name</th>
+          </tr>
+        </thead>
+
+        <tbody></tbody>
+    </table>
+    </div>
+
+    {%else%}
+
+    <label class="control-label" for="rdo-cant-find-species">
+      <input id="rdo-cant-find-species" type="radio" name="species_id"
+             value="CREATE-SPECIES" />
+      There are no species to select from. Create the first one.</label>
+
+    <div class="col-sm-offset-10 col-sm-2">
+      <input type="submit"
+             class="btn btn-primary col-sm-offset-1"
+             value="continue" />
+    </div>
+
+    {%endif%}
+
 </form>
-{%else%}
-<p class="text-danger">
-  <span class="glyphicon glyphicon-exclamation-mark"></span>
-  We could not find species to select from!
-</p>
-{%endif%}
 {%endmacro%}
diff --git a/uploader/templates/species/view-species.html b/uploader/templates/species/view-species.html
index b01864d..2d02f7e 100644
--- a/uploader/templates/species/view-species.html
+++ b/uploader/templates/species/view-species.html
@@ -45,6 +45,12 @@
          title="Create/Edit populations for {{species.FullName}}">
         Manage populations</a>
     </li>
+    <li>
+      <a href="{{url_for('species.platforms.list_platforms',
+               species_id=species.SpeciesId)}}"
+         title="Create/Edit sequencing platforms for {{species.FullName}}">
+        Manage sequencing platforms</a>
+    </li>
   </ol>