For Generations of Web-Tsars to Come

At a high level, this website is a single-page application based on AngularJS. The single-page design principle is aimed at handling state transition and manipulating DOM components within the same page, so as to provide users with a smooth experience comparable to desktop applications. In the meanwhile, this design requires minimum support and maintenance from the server side, keeping the website light-weighted and responsive.

The website is dedicated to the course “Math Everywhere” at Duke University, offered by the Department of Mathematics on a yearly basis. The course is targeted to students with absolutely NO previous exposure to college-level calculus. Any registered students who have taken calculus at Duke at any level are forced to drop the course to make room for those with real needs. As of Spring 2016, the course number is MATH 181.

Duties

Web Service Environment

The public website will be hosted on the math server at

/home/system/httpd/htdocs/courses/math_everywhere/

The development is based on a GitLab repository internal to the math department. All development should be carried out first on a local machine, then pushed to the GitLab repository; then one has to log into the math server, move into the folder above and pull the updates. Keep in mind:

  1. The course website domain is not top-level; the Apache server is run at https://services.math.duke.edu/ while the course website starts at https://services.math.duke.edu/courses/math_everywhere/. This matters when you start making links to local resources, for example writing page routing in js/controllers.js.
  2. The website is basically static html, with absolutely no work done on the server-side.

Technical Skill Set

The web-tsar is expected to have at least basic understanding of the following web-development techniques, up to the level of being able to resolve common issues by googling:

If you would like to develop labs for your module, the following JavaScript visualization libraries can be extremely useful:

If necessary, some references are provided to get you up and running quickly:

When developing locally, it is strongly recommended that you maintain the same folder structure as on the math department server. This faciliates your local testing, and the modifications you made can work seamlessly for the published website. For instance,

mkdir -p test/courses/
cd test/courses/
git clone git@git.math.duke.edu:jonm/math-everywhere.git math_everywhere

After your changes are commited, move back to the top level folder and set up a simple python server:

cd ../../
python -m SimpleHTTPServer 8000 &

Then test your changes by navigating to the following address in your browser:

http://localhost:8000/courses/math_everywhere/

If everything looks good, push your commits to the GitLab repository:

git push
ssh <your account on the math department server>
cd /home/system/httpd/htdocs/courses/math_everywhere/
umask 0022
git pull

If you follow these steps, your commits will work out of the box for the published website.

Routing with Layout and Templates

The entry point to the whole website is the top level index.html. Essentially this is a “layout scaffold” of all pages on this website; all pages (including Home) will be loaded (or injected) into this layout profile at the position

<!-- templates will be injected here -->
<div class="container">
    <div class="{{ pageClass }}" ng-view autoscroll="true"></div>
</div>

Roughly speaking, you can understand the routing mechanism as replacing the line above in index.html with various templates in the pages/ folder. In the tempalte html file, all you need to do is to write HTML within this element. Note that the best practice is to take advantage of the grid system provided by Bootstrap; see pages/contact.html for example. After putting up a new template in pages, say test.html, create a link to it with reference #/test, and update js/controllers.js by chaining $routeProvider with another when clause. For instance, the following when method adds a route that links towards the Home page:

.when('/home', {
    templateUrl : '/courses/math_everywhere/pages/home.html',
    controller  : 'mainController'
})
mewApp.controller('mainController', function($scope) {
});

Note that in templateUrl you should prefix the relative path with /courses/math_everywhere/ because the Apache server in the math department is run on the top level domain.

Structure of a Module

This course mainly consists of a collections of independent modules. The very first step of adding a module to the course website is to create a folder under assets/, with the following sub-folders:

assignments/
labs/
notes/
slides/
worksheets/

For better organization, the name of the module folder better be simple, consisting of only lowercase letters, numbers, or allowable special characters. The meaning of the sub-folders assignments/, notes/, slides/, worksheets/ are pretty self-explanatory; simply drop off pdf files (along with tex files and images used for creating the pdf file, since future instructors might be interested in modifying the contents) in these folders and manually add links to them on the corresponding pages (pages/assignments.html and pages/notes.html) or the navigation bar. The sub-folder labs/ should contain HTML files that will be automatically loaded into the portal page of each module. Here is the folder structure of the Cryptogrpahy module (contained in folder assets/cryptography/) as an example:

cryptography/
├── assignments
│   ├── auto
│   │   └── problem_set-cryptography.el
│   ├── problem_set-cryptography.aux
│   ├── problem_set-cryptography.log
│   ├── problem_set-cryptography.pdf
│   └── problem_set-cryptography.tex
├── labs
│   ├── Decryption.html
│   ├── Factorization.html
│   ├── Fermat.html
│   ├── Fermat_Proof.html
│   ├── Fermat's_Little_Theorem.html
│   ├── Modular_Arithmetic.html
│   ├── Modular_Powers_Calculator.html
│   ├── Modular_Product_Calculator.html
│   ├── RSA_Cryptography.html
│   └── Why_Hard_to_Break.html
├── notes
│   ├── notes-crypto2.pdf
│   └── notes-crypto_Caesar_Hagelin.pdf
├── slides
│   ├── Crypto_slides.pdf
│   ├── intro.pdf
│   └── public_key_crypto_start.pdf
└── worksheets
    ├── decrypting_NBY_etc_sol.pdf
    ├── In_class__Jan_19_2016_A_sol.pdf
    ├── In_class__Jan_19_2016_B_sol.pdf
    ├── In_class__Jan_26,27_2016_sol.pdf
    └── RSA_worksheet_sol.pdf

6 directories, 25 files

We will elaborate below on how to add each of these module components to the website.

Adding Assignments

Adding assignments to pages/assignments.html is probably the simplest task: just add links wrapped in <a></a> elements, together with due dates, to the table at the cente of the page.

Adding Notes, Slides, and Worksheets

Adding notes, slides, and worksheets to pages/notes.html is just a little bit more than work adding assignments. First of all, the entry point is in the dropdown button “Notes” in the top navigation bar, so one should open up index.html, find the unordered list below the line that defines the “Notes” dropdown button, and insert a new item in the dropdown memu. Take cryptography for example:

<li class="dropdown">
    <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Notes<span class="caret"></span></a>
    <ul class="dropdown-menu">
        <li class="trigger-collapse"><a href="#/notes/cryptography">Cryptography</a></li>
    </ul>
</li>

After this, open up pages/notes.html and add in links to the notes and slides. The only thing to keep in mind is that each module should begin with a class featurette-divider horizontal rule, and the name of the module should be used as the id of the divider. This is because a link staring with #notes/ will be routed to the a section of pages/notes.html corresponding to the module to which those notes and slides belong. Here is the beginning part of the Notes & Slides page for the cryptography module:

<hr class="featurette-divider" id="cryptography">

<div class="row">
    <div class="col-lg-1"><h2></h2></div>
    <div class="col-lg-10">
        <h1 class="page-header"><b>Cryptography</b></h1>
        <div class="col-lg-5">
            <h3>Notes</h3>
            <p class="lead">
                <ul>
                    <li><a href="assets/cryptography/notes/notes-crypto_Caesar_Hagelin.pdf"><i>Caesar Codes and Hagelin Cryptograph</i></a></li>
                    <li><a href="assets/cryptography/notes/notes-crypto2.pdf"><i>Public Key Cryptography</i></a></li>
                </ul>
            </p>
            <h3>Slides</h3>
            <p class="lead">
                <ul>
                    <li><a href="assets/cryptography/slides/intro.pdf"><i>Course Introduction</i></a></li>
                    <li><a href="assets/cryptography/slides/Crypto_slides.pdf"><i>Transliteration Schemes</i></a></li>
                    <li><a href="assets/cryptography/slides/public_key_crypto_start.pdf"><i>Fermat's Little Theorem & Why RSA Works</i></a></li>
                </ul>
            </p>
            <h3>Worksheets</h3>
            <p class="lead">
                <ul>
                    <li><a href="assets/cryptography/worksheets/decrypting_NBY_etc_sol.pdf"><i>Substitution Code</i></a></li>
                    <li><a href="assets/cryptography/worksheets/In_class__Jan_19_2016_A_sol.pdf"><i>Modular Product</i></a></li>
                    <li><a href="assets/cryptography/worksheets/In_class__Jan_19_2016_B_sol.pdf"><i>Modular Power</i></a></li>
                    <li><a href="assets/cryptography/worksheets/RSA_worksheet_sol.pdf"><i>RSA</i></a></li>
                    <li><a href="assets/cryptography/worksheets/In_class__Jan_26,27_2016_sol.pdf"><i>Euclid's Algorithm</i></a></li>
                </ul>
            </p>
        </div>
        <div class="col-lg-7">
            <div class="col-lg-7"><h2></h2></div>
            <div class="col-lg-7"><h2></h2></div>
            <img class="featurette-image img-responsive center-block" src="img/M209B.jpg" alt="Cryptography">
        </div>
    </div>
    <div class="col-lg-1"><h2></h2></div>
</div>

Adding Labs

Designing labs and adding them to the course website is probably the trickest part. First of all, same as adding notes and slides, the entry point of all labs in a module is in the top navigation bar, in the dropdown button “Labs”. Thus one should find the unordered list below the following line

<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Labs<span class="caret"></span></a>

and insert a new item in the dropdown menu. Again, take cryptography for example:

<ul class="dropdown-menu">
    <li class="trigger-collapse"><a href="#/lab/cryptography">Cryptography</a></li>
</ul>

A link starting with #/lab/ has two different types of routings, specified in the $routeProvider configuration section in js/controllers.js.

This list of all labs are hand-coded as a hash table in the LabItemList factory in js/controllers.js instead of automatically scanned under the module folder, mainly because the latter order is alphabetical and not likely to be what you want. The list of labs for the cryptography module looks as follows:

labItems['cryptography'] = ["Modular_Arithmetic",
                            "Modular_Product_Calculator",
                            "Modular_Powers_Calculator",
                            "Fermat",
                            "Fermat_Proof",
                            "Fermat\'s_Little_Theorem",
                            "RSA_Cryptography",
                            "Decryption",
                            "Why_Hard_to_Break",
                            "Factorization"];

Each entry in this list corresponds to an HTML file in the lab/ sub-folder of the module folder. For instance, Modular_Arithmetic corresponds to the lab “Modular Arithmetic” stored as assets/cryptography/labs/Modular_Arithmetic.html. Each of these items will be rendered as the page title of the lab, with underscores replaced with spaces. The HTML file for each lab has to follow certain rules to facilicate automatic generation of the pager (navigating to previous/next lab, or go back to the portal page), thus we recommend you start by copying and renaming the boilerplate pages/labTemplate.html and then add your contents to the col-lg-8 element in that template. The complete template looks as follows:

<div ng-include="'pages/labHeader.html'"></div>

<div class="row">
    <div class="col-lg-2"></div>
    <div class="col-lg-8"></div><!-- end of 8-column container -->
    <div class="col-lg-2"></div>
</div>

<div ng-include="'pages/labPager.html'"></div>

<style type="text/css"></style>
<script type="text/javascript"></script>

As described previously, each HTML for an individual lab should be named after the page title you want to show on the page top, with spaces replaced by underscores.

This is pretty much everything you need to know about adding labs to the website. The general procedure can be summarised as follows.

  1. Create individual labs: copy and rename biolerplate pages/labTemplate.html, add contents in the 8-column element <div class="col-lg-8"></div>; any page-specific css/javascript goes into the <style> <script> elements of the boilerplate pages/labTemplate.html; the HTML file for the lab should be named after the title of the lab, with spaces replaced by underscores;
  2. Dump all labs for a module into a sub-folder labs/ under the module folder, and place the module folder under assets/; compile the list of labs in js/controllers.js in the LabItemList factory;
  3. Add an entry point to the lab portal page of the module in the top navigation bar, in the “Labs” dropdown menu.

Adding a Tab in the Top Navigation Bar

You will need this when creating new tabs in the navigation bar, for instance when publishing midterm or final topics.

  1. Creat a placeholder in index.html, within the container of class navbar-wrapper. Find a slot in the unordered list (ul) and put up a list entry. Write in the format href="#/blahblahblah".
  2. Create a page in the pages/ folder, bearing the name blahblahblah.html.
  3. Copy and paste some boilerplate code from contact.html to the new html file, and make changes as seen fit.
  4. Modify js/controllers.js, concatenate $routeProvider with another when clause and initiate a new controller. Since the pages are collected under pages/, you should provide templateUrl that directs there.

Update/Maintain this README File

To convert this Markdown file into HTML, install Pandoc and execute

pandoc -s -S --toc -c css/github-pandoc.css -f markdown_github+pandoc_title_block README -o README.html