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.
history
folder.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:
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
.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.
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.
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 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 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>
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
.
If the link points to only one level below #/lab/
, for example #/lab/cryptography/
, a portal template pages/portal.html
will be loaded. This portal page will load the list of all labs within the module and render them in the center of the page.
If the link points to two levels below #/lab/
, for example #/lab/cryptography/Fermat
, it will be routed to the specific lab in the lab/
sub-folder of the module folder.
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.
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;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;You will need this when creating new tabs in the navigation bar, for instance when publishing midterm or final topics.
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"
.pages/
folder, bearing the name blahblahblah.html
.contact.html
to the new html file, and make changes as seen fit.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.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