# Session 13: Server-Side, Part 1

Harvard Extension School
Fall 2021

Course Web Site: https://cscie12.dce.harvard.edu/

### Topics

1. Announcements
2. David's Project - Nature of America
3. DRY and Sites with more than one page
4. Web Content Management System (Web CMS)
5. Building Pages from Parts: An Introduction to PHP
6. Web Development
7. PHP Example with Courses from Database
8. Querying the Database with SQL
9. Separation of Concerns
10. {{Mustache}} Templates
11. Improving the Hello! Greeting
12. Backend Data - Frontend Templates
13. Sending Email

Session 13: Server-Side, Part 1, slide1
Announcements, slide2
David's Project - Nature of America, slide3
Final Project Notes and Observations, slide4
DRY and Sites with more than one page, slide5
Web Content Management System (Web CMS), slide6
Static Site Generators (SSG), slide7
Building Pages from Parts: An Introduction to PHP, slide8
PHP: Hypertext Processor, slide9
Building a Page from Parts, slide10
Iroquois Constitution, slide11
File Includes with PHP, slide12
Parts that Build the Page, slide13
Recommendation: Keep files well-formed, slide14
Web Development, slide15
Dynamic Content, slide16
Dynamic Content: How does it look?, slide17
Web Program Examples, slide18
A Personal Greeting, slide19
A Personal Greeting, slide20
PHP Example with Courses from Database, slide21
FAS Course Data, slide22
Data Table in a Relational Database, slide23
Querying the Database with SQL, slide24
PHP Script to Connect to Database and Get List of Departments, slide25
Turn this into HTML Output, slide26
The entire "departments-simple.php", slide27
Adding another view - Department Course Listings, slide28
courses.php, slide29
Separation of Concerns, slide30
{{Mustache}} Templates, slide31
Mustache Departments, slide32
Mustache Courses, slide33
Improving the Hello! Greeting, slide34
Hello! Greeting, Improved, slide35
Backend Data - Frontend Templates, slide36
JSON from PHP data, slide37
Front-end courses, slide38
Sending Email, slide39

Presentation contains 39 slides

- img
- img
- img
- img
- img

## Announcements

- Makeup class - Thursday, 8:10pm - Server Side, Part 2. Live and recorded
- Office Hours - Scheduled and Open. Will schedule those after class - there will be options for Wednesday, Friday, Saturday, and Sunday
- Class for Tuesday, December 7 - submit and upvote topics at: https://pollev.com/cscie12
- Tuesday, December 13. Final Project Due and Final Project Presentations [Optional]

## David's Project - Nature of America

- My project report: Final Project Report - Nature of America
- Nature of America - Final Project Site

### Progress

- Functional
  - Google Map working
  - Stamp listing working
  - Menu/navigation dropdown and "active" area
- Needs work
  - Mobile friendly menu

## Final Project Notes and Observations

- Implement only three parts.
  - The rest doesn't have to exist
  - Use `href="#"` to link to those things that don't exist yet
- File structure organization:
  - All of your html files at the top level
  - directory/folder for images, styles, and scripts

        .
        |-- index.html
        |-- hello-harvard.html
        |-- images
        |   |-- harvard.jpg
        |   `-- world.jpg
        |-- scripts
        |   `-- map.js
        `-- styles
            `-- site.css

- lowercase file names and without spaces
  - Better: `my_favorite_teas.html`
  - Worse: `My Favorite Teas.html`
- Within your site, use relative URL links.
  - NOT relative:
    1. `<link rel="stylesheet" href="/Users/david/Desktop/final_project/styles/site.css"/>`
- Site-wide CSS Stylesheet!
  One CSS stylesheet to style all of your HTML pages!

## DRY and Sites with more than one page

DRY = don't repeat yourself

What to do about common items across all pages? Like CDN JS and CSS, local CSS link, local JS script, common header, footer, navigation?

- cut-and-paste
- Static Site Generators (SSG)
- Parts into a whole -- with SSI, PHP
- Web Content Management System (e.g. Wordpress)

## Web Content Management System (Web CMS)

- WordPress "is open source software you can use to create a beautiful website, blog, or app."

## Static Site Generators (SSG)

Static Site Generators listed on Jamstack

### An Example with 11ty (eleventy)

- 11ty.dev (11ty, Eleventy)

#### _template.html

    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="utf-8" />
        <title>{{ title }} | Nature of America</title>
        {% include _htmlhead.html %}
    </head>

    <body>
        <header>
            <h1>Nature of America</h1>
            {% include _navigation.html %}
        </header>
        <main>
            <h2>{{ title }}</h2>
            {{ content }}
        </main>
        {% include _footer.html %}
        {% include _content_templates.html %}
        {% include _blueimp_gallery_templates.html %}
    </body>

    </html>

#### map.html

    ---
    title: Places of First Issue
    layout: _template.html
    ---
    <div id="map">   </div>

## Building Pages from Parts: An Introduction to PHP

### Review of HTTP Request/Response

### Pages from Parts

## PHP: Hypertext Processor

- PHP: Hypertext Processor

From the PHP manual:

PHP, which stands for "PHP: Hypertext Preprocessor" is a widely-used Open Source general-purpose scripting language that is especially suited for Web development and can be embedded into HTML. Its syntax draws upon C, Java, and Perl, and is easy to learn. The main goal of the language is to allow web developers to write dynamically generated web pages quickly, but you can do much more with PHP.

### PHP Example

hello.php

    <?php
    $greeting = "Hello, World!";
    ?>
    <html lang="en">
    <head><title>Hello</title></head>
    <body>
    <h1><?php echo($greeting) ?></h1>
    </body>
    </html>

## Building a Page from Parts

### Why?

- Common elements of site are in one place and included throughout the site
  Useful to include documents or information that is used repeatedly throughout a site, such as common headers, footers, and navigation elements. You can change these chunks in one place and have an effect on the entire site!
- Documents (or parts of pages) that change often
  Useful to include documents or information that change frequently; only the "included" file needs to be updated, not the page itself. Also the person or program editing the file need only have permissions to edit the "included" file, not the actual HTML document that includes it; only the data in the "include" file needs to be written, not the entire HTML page.
- Document Information
  Useful to include information specific about a document, such as last modified date, URI, size.

### Techniques

- PHP and file include
- Apache Server Side Includes (SSI)

## Iroquois Constitution

Iroquois Constitution (also this demonstrates using JavaScript to make the navigation 'work' with an "iamhere" id.)

Iroquois Constitution Zip File containing HTML, CSS, and "Include" files.

## File Includes with PHP

    <!DOCTYPE html>
    <html>
      <head>
        <title>The Great Binding Law, Gayanashagowa (Constitution of the Iroquois Nations)</title>
        <?php include("inc/htmlhead.php"); ?>
      </head>
      <body id="part1">
        <?php include("inc/header.php"); ?>
        <?php include("inc/nav.php"); ?>
        <main>
          <?php include("inc/content1.php"); ?>
        </main>
        <?php include("inc/footer.php"); ?>
      </body>
    </html>

### Files

    |-- 1.php
    |-- 10.php
    |-- 11.php
    |-- 12.php
    |-- 13.php
    |-- 14.php
    |-- 15.php
    |-- 16.php
    |-- 2.php
    |-- 3.php
    |-- 4.php
    |-- 5.php
    |-- 6.php
    |-- 7.php
    |-- 8.php
    |-- 9.php
    |-- inc
    |   |-- content1.php
    |   |-- content10.php
    |   |-- content11.php
    |   |-- content12.php
    |   |-- content13.php
    |   |-- content14.php
    |   |-- content15.php
    |   |-- content16.php
    |   |-- content2.php
    |   |-- content3.php
    |   |-- content4.php
    |   |-- content5.php
    |   |-- content6.php
    |   |-- content7.php
    |   |-- content8.php
    |   |-- content9.php
    |   |-- footer.php
    |   |-- header.php
    |   |-- htmlhead.php
    |   `-- nav.php
    |-- scripts
    |   `-- highlightnavigation.js
    `-- styles
        `-- site.css

## Parts that Build the Page

### Starting File (1.php)

    <!DOCTYPE html>
    <html>
      <head>
        <title>The Great Binding Law, Gayanashagowa (Constitution of the Iroquois Nations)</title>
        <?php include("inc/htmlhead.php"); ?>
      </head>
      <body id="part1">
        <?php include("inc/header.php"); ?>
        <?php include("inc/nav.php"); ?>
        <main>
          <?php include("inc/content1.php"); ?>
        </main>
        <?php include("inc/footer.php"); ?>
      </body>
    </html>

### HTML Head Content - htmlhead.php

    <meta charset="utf-8"/>
    <link rel="stylesheet" href="./styles/site.css" />
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script src="scripts/highlightnavigation.js"> </script>

### Header - header.php

    <header><h1>Constitution of the Iroquois Nations</h1></header>

### Navigation - nav.php

    <nav>
    <ul id="mainnav">
    <li id="navpart1"><a href="1.php">The Great Binding Law, Gayanashagowa</a></li>
    <li id="navpart2"><a href="2.php">Rights, Duties and Qualifications of Lords</a></li>
    <li id="navpart3"><a href="3.php">Election of Pine Tree Chiefs</a></li>
    <li id="navpart4"><a href="4.php">Names, Duties and Rights of War Chiefs</a></li>
    <li id="navpart5"><a href="5.php">Clans and Consanguinity</a></li>
    <li id="navpart6"><a href="6.php">Official Symbolism</a></li>
    <li id="navpart7"><a href="7.php">Laws of Adoption</a></li>
    <li id="navpart8"><a href="8.php">Laws of Emigration</a></li>
    <li id="navpart9"><a href="9.php">Rights of Foreign Nations</a></li>
    <li id="navpart10"><a href="10.php">Rights and Powers of War</a></li>
    <li id="navpart11"><a href="11.php">Treason or Secession of a Nation</a></li>
    <li id="navpart12"><a href="12.php">Rights of the People of the Five Nations</a></li>
    <li id="navpart13"><a href="13.php">Religious Ceremonies Protected</a></li>
    <li id="navpart14"><a href="14.php">The Installation Song</a></li>
    <li id="navpart15"><a href="15.php">Protection of the House</a></li>
    <li id="navpart16"><a href="16.php">Funeral Addresses</a></li>
    </ul>
    </nav>

### Footer - footer.php

    <footer>
    Text form prepared by Gerald Murphy (The Cleveland Free-Net - aa300). Distributed by the Cybercasting Services Division of the National Public Telecomputing Network. Rendered into HTML by <a href="mailto:jon.roland@the-spa.com">Jon Roland</a> of the Constitution Society.  (NPTN). Permission is hereby granted to download, reprint, and/or otherwise redistribute this file, provided appropriate point of origin credit is given to the preparer(s), the National Public Telecomputing Network and the Constitution Society.
    <div class="note">
    <p>Additional information about the Iroquois nations and their constitution are available:</p>
    <ul>
    <li><a href="http://www.sixnations.org/">Haudenosaunee:  People Building a Long House</a></li>
    <li><a href="http://www.tuscaroras.com/graydeer/influenc/page1.htm">The Influence of the Great Law of Peace on the the United States constitution:  an Haudenosaunee (Iroquois) Perspective</a></li>
    <li><a href="http://www.ratical.org/many_worlds/6Nations/index.html">The Six Nations:  Oldest Living Participatory Democracy on Earth</a></li>
    <li><a href="http://www.carnegiemuseums.org/cmnh/exhibits/north-south-east-west/iroquois/">The Iroquois nations of the Northeast</a></li>
    <li><a href="http://www.iroquoismuseum.org/">Iroquois Indian Museum</a></li>
    </ul>
    </div>
    </footer>

## Recommendation: Keep files well-formed

### Don't do this: Breaking a page in half

This technique is not recommended. The first include file contains the top "half" of the page; the content follows; the second include file contains the bottom "half" of the page. In this technique, the `html` ,`body`, and perhaps other elements are started in the "top half" and their end tags are in "bottom half." The page delivered to the browser does validate, but the individual parts on the server are not well-formed, which can cause some confusion when editing a file.

    <?php include("header-tophalf.html"); ?>
      Lorem ipsum dolor sit amet, consectetuer adipiscing ...
    <?php include("footer-bottomhalf.html"); ?>

### Keeping things well-formed

    <!DOCTYPE html>
    <html>
      <head>
        <title>Lecture Notes</title>
        <link rel="stylesheet" href="styles/site.css" />
      </head>
      <body>
        <header>
          <?php include("inc/header.php") ?>
        </header>
        <nav>
          <?php include("inc/nav.php") ?>
        </nav>
        <main>
          Lorem ipsum dolor sit amet, consectetuer adipiscing ...
        </main>
      </body>
    </html>

## Web Development

Language | Frameworks/Platforms
--- | ---
JavaScript | "Back-end": Node, Express "Front-end": React, Vue, Angular, Ember
PHP | Laravel, Symfony, CodeIgniter, CakePHP CMS: WordPress, Drupal, Joomla, Concrete5, GetSimple
Python | Django, Flask, Zope, Plone
Ruby | Rails

## Dynamic Content

- Internal and persistent (e.g. PHP in Apache)
- External and persistent (e.g. FastCGI)

## Dynamic Content: How does it look?

- program that outputs Web content
  programs with HTML embedded
- Web content that has embedded programming
  HTML with programs embedded
- Separation of Concerns (SOC)
  MVC, Model-View-Controller, and its variants

## Web Program Examples

Markup or content is embedded within a program; program embedded into markup

### first.py - Python

first.py

    ##!/usr/bin/python3
    print("Content-type: text/html\n\n")
    print("<html><head><title>Hello World!</title></head>")
    print("<body><h1>Hello, World!</h1></body></html>")

### first.php - PHP

first.php

    <?php
    echo('<html><head><title>First PHP</title></head><body>');
    echo('<h1>Hello!</h1>');
    echo('</body></html>');
    ?>

### second.php - PHP

second.php
program statements within markup

    <?php
          $title = "Hello World!";
    ?>
    <!DOCTYPE html>
      <head>
        <meta charset="utf-8" />
        <title><?php echo($title) ?></title>
      </head>
      <body>
        <h1><?php echo($title) ?></h1>
      </body>
    </html>

## A Personal Greeting

- third.php
- third.php?name=John%20Harvard

    <?php
          $name = $_GET["name"];
    ?>
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Greeting Page</title>
      </head>
      <body>
        <h1>Hello, <?php echo($name) ?>!</h1>
      </body>
    </html>

## A Personal Greeting

Without a "name", present the user a form. With a name, provide a greeting.

- fourth.php
- fourth.php?name=John%20Harvard

    <?php
          $name = $_GET["name"];
    ?>
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8"/>
        <title>Greeting Page</title>
      </head>
      <body>
        <?php
        if ($name) {
          echo("<h1>Hello, $name!</h1>");
        } else {
          echo('<h1><label for="input_name">Enter name:</label></h1>');
          echo('<form method="get">');
          echo('<input type="text" name="name" id="input_name"/>');
          echo('<br /><input type="submit" />');
          echo('<br /><input type="reset" />');
        }
    ?>
      </body>
    </html>

## PHP Example with Courses from Database

- https://cscie12.dce.harvard.edu/cgi/courses/departments.php

## FAS Course Data

### Course Data in a Spreadsheet

## Data Table in a Relational Database

RDBMS = Relational Database Management System

- Postgres
- MySQL
- Oracle
- Microsoft SQL Server

### Course Data in RDBMS Table

Course data for Faculty of Arts & Sciences is in a mysql database on cscie12students (username: class; database name: coursecatalog)

SQL:

    describe courses

Terminal:

    cscie12students$ mysql -u class coursecatalog
    Welcome to the MySQL monitor.  Commands end with ; or \g.

    mysql> describe courses;
    +------------------------------+--------------+------+-----+---------+-------+
    | Field                        | Type         | Null | Key | Default | Extra |
    +------------------------------+--------------+------+-----+---------+-------+
    | acad_year                    | year(4)      | YES  |     | NULL    |       |
    | cat_num                      | int(9)       | YES  |     | NULL    |       |
    | offered                      | char(1)      | YES  |     | NULL    |       |
    | department_code              | varchar(15)  | YES  |     | NULL    |       |
    | department_short             | varchar(80)  | YES  |     | NULL    |       |
    | department_long              | varchar(200) | YES  |     | NULL    |       |
    | course_group_code            | varchar(10)  | YES  |     | NULL    |       |
    | course_group_long            | varchar(200) | YES  |     | NULL    |       |
    | num_int                      | int(9)       | YES  |     | NULL    |       |
    | num_char                     | varchar(15)  | YES  |     | NULL    |       |
    | term_pattern_code            | int(5)       | YES  |     | NULL    |       |
    | fall_term                    | char(1)      | YES  |     | NULL    |       |
    | spring_term                  | char(1)      | YES  |     | NULL    |       |
    | term                         | varchar(100) | YES  |     | NULL    |       |
    | title                        | text         | YES  |     | NULL    |       |
    | course_type                  | varchar(100) | YES  |     | NULL    |       |
    | course_level_code            | char(1)      | YES  |     | NULL    |       |
    | course_level                 | varchar(200) | YES  |     | NULL    |       |
    | credit_code                  | int(5)       | YES  |     | NULL    |       |
    | credit                       | varchar(50)  | YES  |     | NULL    |       |
    | instructor_approval_required | char(1)      | YES  |     | NULL    |       |
    | meeting_time                 | text         | YES  |     | NULL    |       |
    | faculty_text                 | text         | YES  |     | NULL    |       |
    | description                  | text         | YES  |     | NULL    |       |
    | prerequisites                | text         | YES  |     | NULL    |       |
    | notes                        | text         | YES  |     | NULL    |       |
    +------------------------------+--------------+------+-----+---------+-------+
    26 rows in set (0.00 sec)

## Querying the Database with SQL

    select [field names]
    from   [table name]
    where  [condition]

### Selecting Fields from a Course

SQL Input:

    select
        cat_num, department_short, num_int, title, faculty_text
    from
        courses
    where
        cat_num = 22304

    mysql> select cat_num, department_short, num_int, title, faculty_text  from courses where cat_num = 22304 ;
    +---------+------------------+---------+--------------------------------------+-------------------------+
    | cat_num | department_short | num_int | title                                | faculty_text            |
    +---------+------------------+---------+--------------------------------------+-------------------------+
    |   22304 | Astronomy        |      17 | Galactic and Extragalactic Astronomy | Daniel James Eisenstein |
    +---------+------------------+---------+--------------------------------------+-------------------------+
    1 row in set (0.01 sec)

### Selecting List of Departments

SQL Input:

    select distinct department_code, department_short from courses

Terminal Output:

    mysql> SELECT distinct department_code, department_short FROM courses order by department_short ;
    +-----------------+----------------------------------------------------------+
    | department_code | department_short                                         |
    +-----------------+----------------------------------------------------------+
    | AAAS            | African and African American Studies                     |
    | AMER            | American Studies                                         |
    | ANTH            | Anthropology                                             |
    | URBP            | Architecture, Landscape Architecture, and Urban Planning |
    | ABEA            | Asian Studies Programs                                   |
    | ASTR            | Astronomy                                                |
    | BSDM            | Biological Sciences in Dental Medicine                   |
    | BSPH            | Biological Sciences in Public Health                     |
    | BIPH            | Biophysics                                               |
    | BIST            | Biostatistics                                            |
    | CELT            | Celtic Languages and Literatures                         |
    | CHPB            | Chemical and Physical Biology                            |
    | CHBI            | Chemical Biology                                         |
    | CHEM            | Chemistry and Chemical Biology                           |
    | CPLT            | Comparative Literature                                   |
    | DRAM            | Dramatic Arts                                            |
    | E&PS            | Earth and Planetary Sciences                             |
    | EALC            | East Asian Languages and Civilizations                   |
    | ECON            | Economics                                                |
    | DEAS            | Engineering and Applied Sciences                         |
    | ENGH            | English                                                  |
    | ESPP            | Environmental Science and Public Policy                  |
    | EXPO            | Expository Writing                                       |
    | FOLK            | Folklore and Mythology                                   |
    | FRSP            | Freshman Seminars                                        |
    | GEN ED          | General Education                                        |
    | GERM            | Germanic Languages and Literatures                       |
    | GLOBHLTH        | Global Health and Health Policy                          |
    | GOVM            | Government                                               |
    | HPOL            | Health Policy                                            |
    | HIST            | History                                                  |
    | HLIT            | History and Literature                                   |
    | HAA             | History of Art and Architecture                          |
    | HSCI            | History of Science                                       |
    | HSEM            | House Seminars                                           |
    | HEB             | Human Evolutionary Biology                               |
    | HUM             | Humanities                                               |
    | LSCI            | Life Sciences                                            |
    | LING            | Linguistics                                              |
    | MATH            | Mathematics                                              |
    | MDSC            | Medical Sciences                                         |
    | MDST            | Medieval Studies                                         |
    | MEST            | Middle Eastern Studies                                   |
    | MBB             | Mind, Brain, and Behavior                                |
    | MCB             | Molecular and Cellular Biology                           |
    | MUSC            | Music                                                    |
    | NELC            | Near Eastern Languages and Civilizations                 |
    | NEURO           | Neurobiology                                             |
    | NODEPT          | No Department                                            |
    | BIOE            | Organismic and Evolutionary Biology                      |
    | PHIL            | Philosophy                                               |
    | PSCI            | Physical Sciences                                        |
    | PHYS            | Physics                                                  |
    | PSYC            | Psychology                                               |
    | RSEA            | Regional Studies - East Asia                             |
    | ROML            | Romance Languages and Literatures                        |
    | REECA           | Russia, Eastern Europe, and Central Asia                 |
    | SLAV            | Slavic Languages and Literatures                         |
    | SPOL            | Social Policy                                            |
    | SOST            | Social Studies                                           |
    | SOCL            | Sociology                                                |
    | SAST            | South Asian Studies                                      |
    | SPCN            | Special Concentrations                                   |
    | STAT            | Statistics                                               |
    | SCRB            | Stem Cell and Regenerative Biology                       |
    | WMGS            | Studies of Women, Gender, and Sexuality                  |
    | SBIO            | Systems Biology                                          |
    | CLAS            | The Classics                                             |
    | RELG            | The Study of Religion                                    |
    | UKRA            | Ukrainian Studies                                        |
    | VES             | Visual and Environmental Studies                         |
    +-----------------+----------------------------------------------------------+
    71 rows in set (0.00 sec)

## PHP Script to Connect to Database and Get List of Departments

    #!/usr/bin/php
    <?php
    // Connecting, selecting database
      $mysqli = new mysqli('localhost','class','cscie12','coursecatalog');
      if ($mysqli->connect_errno) {
          echo "Failed to connect to mysql: ".$mysqli->connect_errno." ".$mysqli->connect_error;
      }

    // Performing SQL query
    $query = 'SELECT distinct department_short, department_code FROM courses order by department_short';
    $result = $mysqli->query($query);

    // iterating through results
    while ($row = $result->fetch_assoc()){
      echo $row['department_code'];
      echo "\t";
      echo $row['department_short'];
      echo "\n";
    }
    ?>

### Output

[dheitmey@apophis courses]$ php dept-txt.php AAAS African and African American Studies AMER American Studies ANTH Anthropology URBP Architecture, Landscape Architecture, and Urban Planning ABEA Asian Studies Programs ASTR Astronomy BSDM Biological Sciences in Dental Medicine BSPH Biological Sciences in Public Health BIPH Biophysics BIST Biostatistics CELT Celtic Languages and Literatures CHPB Chemical and Physical Biology CHBI Chemical Biology CHEM Chemistry and Chemical Biology CPLT Comparative Literature DRAM Dramatic Arts E&PS Earth and Planetary Sciences EALC East Asian Languages and Civilizations ECON Economics DEAS Engineering and Applied Sciences ENGH English ESPP Environmental Science and Public Policy EXPO Expository Writing FOLK Folklore and Mythology FRSP Freshman Seminars GEN ED General Education GERM Germanic Languages and Literatures GLOBHLTH Global Health and Health Policy GOVM Government HPOL Health Policy HIST History HLIT History and Literature HAA History of Art and Architecture HSCI History of Science HSEM House Seminars HEB Human Evolutionary Biology HUM Humanities LSCI Life Sciences LING Linguistics MATH Mathematics MDSC Medical Sciences MDST Medieval Studies MEST Middle Eastern Studies MBB Mind, Brain, and Behavior MCB Molecular and Cellular Biology MUSC Music NELC Near Eastern Languages and Civilizations NEURO Neurobiology NODEPT No Department BIOE Organismic and Evolutionary Biology PHIL Philosophy PSCI Physical Sciences PHYS Physics PSYC Psychology RSEA Regional Studies - East Asia ROML Romance Languages and Literatures REECA Russia, Eastern Europe, and Central Asia SLAV Slavic Languages and Literatures SPOL Social Policy SOST Social Studies SOCL Sociology SAST South Asian Studies SPCN Special Concentrations STAT Statistics SCRB Stem Cell and Regenerative Biology WMGS Studies of Women, Gender, and Sexuality SBIO Systems Biology CLAS The Classics RELG The Study of Religion UKRA Ukrainian Studies VES Visual and Environmental Studies

## Turn this into HTML Output

    <?php
    // Connecting, selecting database
      $mysqli = new mysqli('localhost','class','cscie12','coursecatalog');
      if ($mysqli->connect_errno) {
          echo "Failed to connect to mysql: ".$mysqli->connect_errno." ".$mysqli->connect_error;
      }

    // Performing SQL query
    $query = 'SELECT distinct department_short, department_code FROM courses order by department_short';
    $result = $mysqli->query($query);

    // iterating through results
    echo "<ul>\n";
    while ($row = $result->fetch_assoc()) {
      echo "<li>";
        echo $row['department_short'];
        echo "</li>\n";
     }
    echo "</ul>\n";
    ?>

## The entire "departments-simple.php"

- https://cscie12.dce.harvard.edu/cgi/courses/departments-simple.php

    <!DOCTYPE html>
    <html>
     <head>
      <title>Departments</title>
      <link rel="stylesheet" href="site.css" type="text/css"/>
     </head>
     <body>
    <h1>Faculty of Arts &amp; Sciences</h1>
    <h2>Departments</h2>

    <?php
    // Connecting, selecting database
      $mysqli = new mysqli('localhost','class','cscie12','coursecatalog');
      if ($mysqli->connect_errno) {
          echo "Failed to connect to mysql: ".$mysqli->connect_errno." ".$mysqli->connect_error;
      }

    // Performing SQL query
    $query = 'SELECT distinct department_short, department_code FROM courses order by department_short';
    $result = $mysqli->query($query);

    // iterating through results
    echo "<ul>\n";
    while ($row = $result->fetch_assoc()) {
      echo "<li>";
        echo $row['department_short'];
        echo "</li>\n";
     }
    echo "</ul>\n";

    // Free resultset
    $result->free();
    // Close connection
    $mysqli->close();

    ?>

     </body>
    </html>

## Adding another view - Department Course Listings

Create another PHP file that displays course information based upon a department_code parameter.

- `courses.php` - take a "department_code" parameter and produce alist of courses for that department.

Need to link to to courses.php:

- courses.php?department_code=CHEM
- courses.php?department_code=MCB

Modify the department listing to include the hyperlink:

    <!DOCTYPE html>
    <html>
     <head>
      <title>Departments</title>
      <link rel="stylesheet" href="site.css" type="text/css"/>
     </head>
     <body>
    <h1>Faculty of Arts &amp; Sciences</h1>
    <h2>Departments</h2>
    <?php
    // Connecting, selecting database
      $mysqli = new mysqli('localhost','class','cscie12','coursecatalog');
      if ($mysqli->connect_errno) {
          echo "Failed to connect to mysql: ".$mysqli->connect_errno." ".$mysqli->connect_error;
      }

    // Performing SQL query
    $query = 'SELECT distinct department_short, department_code FROM courses order by department_short';
    $result = $mysqli->query($query);

    // Printing results in HTML
    echo "<ul>\n";
    while ($row = $result->fetch_assoc()) {
      echo "<li>";
      echo "<a href=\"courses.php?department_code=$row[department_code]\">$row[department_short]</a>";
      echo "</li>\n";
    }
    echo "</ul>\n";

    // Free resultset
    $result->free();
    // Close connection
    $mysqli->close();

    ?>

    </body>
    </html>

## courses.php

- courses.php?department_code=CHEM
- courses.php?department_code=MCB

    <!DOCTYPE html>
    <html>
     <head>
      <title>FAS Courses</title>
      <link rel="stylesheet" href="site.css" type="text/css"/>
     </head>
     <body>
    <h1>Faculty of Arts &amp; Sciences</h1>
    <p><a href="departments.php">Return to Department List</a></p>
    <h2>Department <?php echo $_GET['department_code'] ?></h2>
    <?php
    // Connecting, selecting database
      $mysqli = new mysqli('localhost','class','cscie12','coursecatalog');
      if ($mysqli->connect_errno) {
          echo "Failed to connect to mysql: ".$mysqli->connect_errno." ".$mysqli->connect_error;
      }
    $dept_code = $_GET['department_code'];
    $sqlescaped_dept_code = $mysqli->real_escape_string($dept_code);

    // Performing SQL query
    $query = 'SELECT course_group_long, num_int, num_char, term, title, description, faculty_text';
    $query .= ' from courses where department_code = ';
    $query .= "'".$sqlescaped_dept_code."'";
    $query .= ' order by course_group_long, num_int, num_char, title';

    $result = $mysqli->query($query);

    // Printing results in HTML
         echo "<table cellspacing='0' cellpadding='0'>\n";
    $i = 0;
         while ($row = $result->fetch_assoc()) {
           $class = $i++ % 2 ? 'evenrow' : 'oddrow' ;
           echo "\t<tr class='$class'>\n";
           echo "<td class='abbrev'>$row[course_group_long] $row[num_int] $row[num_char]</td>";
           echo "<td class='long'><strong>$row[title]</strong><br/>";
           echo "<span class='faculty'>$row[faculty_text]</span>";
           echo "<p class='description'>$row[description]</p></td>";
           echo "\t</tr>\n";
         }
    echo "</table>\n";

    // Free resultset
    $result->free();
    // Close connection
    $mysqli->close();
    ?>

    </body>
    </html>

## Separation of Concerns

Separate the data model from the view template!

MVC design pattern separates:

- Model. data model
- View. user interface
- Controller. control and flow logic

## {{Mustache}} Templates

{{mustache}} is another widely used template system for JavaScript (and other languages!).

## Mustache Departments

### Mustache Template

mustache-dept.php

### PHP

    <?php
    // Connecting, selecting database
      $mysqli = new mysqli('localhost','class','cscie12','coursecatalog');
      if ($mysqli->connect_errno) {
          echo "Failed to connect to mysql: ".$mysqli->connect_errno." ".$mysqli->connect_error;
      }

    // Performing SQL query
    $query = 'SELECT distinct department_short, department_code FROM courses order by department_short';
    $result = $mysqli->query($query);

    $i=0;
    while ($row = $result->fetch_assoc()) {
      $results[$i++] = $row;
    }

    $template_data['departments'] = $results;

    // Process with Mustache Template
    include('lib/Mustache.php');

    $m = new Mustache;
    $template_file = 'mustache_templates/departments.html';
    $template_contents = file_get_contents($template_file);
    echo $m->render($template_contents, $template_data);

    // Free resultset and close connection
    $result->free();
    $mysqli->close();
    ?>

### Mustache Template

mustache_templates/departments.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Departments</title>
        <link rel="stylesheet" href="site.css" type="text/css"/>
      </head>
      <body>
       <h1>Faculty of Arts &amp; Sciences</h1>
       <h2>Departments</h2>
    <ul>
    {{#departments}}
         <li>
           <a href="mustache-courses.php?department_code={{department_code}}">{{department_short}}</a>
         </li>
    {{/departments}}
    </ul>
      </body>
    </html>

## Mustache Courses

    <!DOCTYPE html>
    <html>
     <head>
      <title>Courses: {{department_name}}</title>
      <link rel="stylesheet" href="site.css" type="text/css"/>
     </head>
     <body>
    <h1>Faculty of Arts &amp; Sciences</h1>
    <p><a href="mustache-dept.php">Return to Department List</a></p>
    <h2>{{department_name}}</h2>
    <table cellspacing="0" cellpadding="0">
    {{#courses}}
      <tr>
      <td class="abbrev">{{course_group_long}} {{num_int}}{{num_char}}</td>
      <td class="long">
        <strong>{{title}}</strong>
        <br/>
        <span class="faculty">{{faculty_text}}</span>
        <p class="description">
          {{description}}
        </p>
      </td>
      </tr>
    {{/courses}}
    </table>
    </body>
    </html>

## Improving the Hello! Greeting

### We started with

Without a "name", present the user a form. With a name, provide a greeting.

- fourth.php
- fourth.php?name=John%20Harvard

    <?php
          $name = $_GET["name"];
    ?>
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Greeting Page</title>
      </head>
      <body>
        <?php
          if ($name) {
            echo("<h1>Hello, $name!</h1>");
          } else {
            echo('<h1><label for="input_name">Enter name:</label></h1>');
            echo('<form method="get">');
            echo('<input type="text" name="name" id="input_name"/>');
            echo('<br /><input type="submit" />');
            echo('<br /><input type="reset" />');
          }
        ?>
      </body>
    </html>

## Hello! Greeting, Improved

- greeting/index.php
- greeting/index.php?name=John+Harvard

Three files: one code; two templates

- index.php
- greeting.html
- form.html

### index.php

    <?php
    $name = $_GET["name"];

    // figure out which template is needed
    if ($name) {
      $template_file = 'greeting.html';
    } else {
      $template_file = 'form.html';
    }
    $template_contents = file_get_contents($template_file);
    $template_data['name'] = $name;

    // Process with Mustache Template
    include('lib/Mustache.php');
    $m = new Mustache;

    echo $m->render($template_contents, $template_data);

    ?>

### greeting.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Greeting Page for {{name}}</title>
      </head>
      <body>
          <h1>Hello, {{name}}!</h1>
      </body>
    </html>

### form.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Greeting Page</title>
      </head>
      <body>
          <h1><label for="input_name">Enter name:</label></h1>
          <form method="get">
          <input type="text" name="name" id="input_name"/>
          <br /><input type="submit" />
          <br /><input type="reset" />
      </body>
    </html>

## Backend Data - Frontend Templates

Departments

- json-dept.php - PHP script that produces JSON
- fe-departments.html - uses Handlebars

Courses

- json-courses?department_code=CHEM.php - PHP script that produces JSON
- fe-courses.html?department_code=CHEM - uses Handlebars

## JSON from PHP data

    <?php

    // Connecting, selecting database
      $mysqli = new mysqli('localhost','class','cscie12','coursecatalog');
      if ($mysqli->connect_errno) {
          echo "Failed to connect to mysql: ".$mysqli->connect_errno." ".$mysqli->connect_error;
      }
    $dept_code = $_GET['department_code'];
    $sqlescaped_dept_code = $mysqli->real_escape_string($dept_code);

    // Performing SQL query
    $query = 'SELECT course_group_long, num_int, num_char, term, title, description, faculty_text';
    $query .= ' from courses where department_code = ';
    $query .= "'".$sqlescaped_dept_code."'";
    $query .= ' order by course_group_long, num_int, num_char, title';

    $result = $mysqli->query($query);

    $i = 0;
    while ($row = $result->fetch_assoc()) {
      $results[$i++] = $row;
    }

    $template_data['courses'] = $results;
    $template_data['department_name'] = $dept_code;

    header('Content-type: application/json');
    echo json_encode($template_data);

    // free and close
    $result->free();
    $mysqli->close();
    ?>

## Front-end courses

    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Departments</title>
        <link rel="stylesheet" href="site.css" type="text/css"/>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js" integrity="sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==" crossorigin="anonymous"></script>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
        <script>
        let dataUrl = 'json-courses.php'

        var urlParams = new URLSearchParams(window.location.search);
        console.log(urlParams.get('department_code'));
        let department_code = urlParams.get('department_code');
    $(document).ready(function(){
      $.getJSON(dataUrl,{"department_code": department_code},
        function (data) {
          console.log(data);
          var mysource = $('#courses-list-template').html();
          var mytemplate = Handlebars.compile(mysource);
          var myresult = mytemplate(data)
          $('#courses-list').html(myresult);
      });
    })
        </script>
      </head>
      <body>
       <h1>Faculty of Arts &amp; Sciences</h1>

       <div id="courses-list">

       </div>

    <div id="courses-list-template" class="handlebars">
        <h2>{{ department_name }}</h2>
        <p>{{ courses.length }} courses</p>
    <hr/>    <ul>
            {{#courses}}
            <li>{{course_group_long}} {{num_int}}{{num_char}}
                <strong>{{title}}</strong>
                <br/>
                <span class="faculty">{{faculty_text}}</span>
                <p class="description">
                  {{description}}
                </p>
                </li>
            {{/courses}}
            </ul>
    </div>
      </body>
    </html>

## Sending Email

Mail service -- e.g. Mailgun, Sendgrid, etc.

### submit.php Example (uses Mailgun)

    <?php require_once 'vendor/autoload.php';

    $loader = new \Twig\Loader\FilesystemLoader('./templates');
    $twig = new \Twig\Environment($loader, [
        'cache' => './compilation_cache',
        'debug' => true,
        'auto_reload' => true
    ]);
    $requestTime = new DateTime();
    $requestTime->setTimestamp($_SERVER['REQUEST_TIME']);
    $requestTimeHuman = $requestTime->format('Y-m-d\TH:i:s');

    $echocontent = $twig->render('form-response-template.html',
         [
         'getparams' => $_GET,
         'postparams' => $_POST,
         'httpheaders' => getallheaders(),
         'httpmethod' => $_SERVER['REQUEST_METHOD'],
         'serverinfo' => $_SERVER,
         'requesttime' => $requestTimeHuman,
         'httpreferer' => $_SERVER['HTTP_REFERER']
         ]);
    ?>

    <?php

    require 'vendor/autoload.php';
    use Mailgun\Mailgun;

    $mailto = filter_var($_POST['__mailto'], FILTER_VALIDATE_EMAIL);
    $mailkey = '';
    if (preg_match('/^csci(e|s)12\-(spring|summer|fall)-\d{4}-[a-z]+[0-9]+$/',$_POST['__mailkey'])) {
       $mailkey = $_POST['__mailkey'];
    }

    // only send if POST and if __mailto and if __mailkey exist

    if (strcmp($_SERVER['REQUEST_METHOD'],'POST') == 0 && $mailto && $mailkey ) {
      error_log("FormSubmit | MAILGUN | $mailkey | $mailto |");
      // First, instantiate the SDK with your API credentials
      $MG_API_KEY = getenv('MG_API_KEY');
      $MG_DOMAIN = getenv('MG_DOMAIN');
      $MG_FROM = getenv('MG_FROM');

      $mg = Mailgun::create($MG_API_KEY); // For US servers
      $domain = $MG_DOMAIN;

      // Now, compose and send your message.
      // $mg->messages()->send($domain, $params);
      $mg->messages()->send($domain, [
        'from'    => $MG_FROM,
        'to'      => $mailto,
        'subject' => 'Form Submission',
        'html'    => $echocontent
      ]);
    }

    echo($echocontent);
    ?>

### form_response_template.html

This is a PHP "Twig" template.

    <DOCTYPE html>
    <html lang="en">
      <head><title>Form Submission</title>
        <style>
          body, * { font-family: helvetica, sans-serif; }
          body { margin: 1rem 5%; }
          h2 { margin-top: 1.5rem; }
          table, td, th, tr { border-collapse: collapse; }
          table td, table th { border-collapse: collapse; vertical-align: top; padding: 0.5rem; border: thin solid #101010; }
          table thead tr { color: #ffffff;  background-color: rgb(100,100,100); font-size: larger;}
          table tbody tr:nth-child(even) { background-color: rgb(240,240,240); }
          table tbody tr th { text-align: left; }
          footer { margin-top: 4rem; padding: 0.5rem; background-color: rgb(240,240,240); border-top: thin solid black; }
          footer p { margin-top: 0.5em; margin-bottom: 0.5em; }
        </style>
      </head>

      <body>
        <h1>Form Submission</h1>
        {% if getparams %}
        <h2>GET Parameters</h2>
        <table>
          <thead>
            <tr><th>Name</th><th>Value</th></tr>
          </thead>
          <tbody>
          {% for key, value in getparams %}
          <tr>
            <th>{{ key }}</th>
            <td>
              {% if value is iterable %}
              {% for v in value %}
                {{ v }}{% if not(loop.last) %},<br/>{% endif %}
              {% endfor %}
              {% else %}
                {{ value }}
              {% endif %}
            </td>
          </tr>
          {% endfor %}
          </tbody>
        </table>
        {% endif %}

        {% if postparams %}
        <h2>POST Parameters</h2>
        <table>
          <thead>
            <tr><th>Name</th><th>Value</th></tr>
          </thead>
          <tbody>
          {% for key, value in postparams %}
          <tr>
            <th>{{ key }}</th>
            <td>
              {% if value is iterable %}
              {% for v in value %}
                {{ v }}{% if not(loop.last) %},<br/>{% endif %}
              {% endfor %}
              {% else %}
                {{ value }}
              {% endif %}
            </td>
          </tr>
          {% endfor %}
          </tbody>
        </table>
        {% endif %}

        {% if serverinfo %}
        <h2>Request Information</h2>
        <table>
          <thead>
            <tr><th>Name</th><th>Value</th></tr>
          </thead>
          <tbody>
            <tr><th>Request Time</th><td>{{ requesttime }}</td></tr>
            <tr><th>Remote Address</th><td>{{ serverinfo['REMOTE_ADDR'] }}</td></tr>
            <tr><th>HTTP Referrer</th><td><a href="{{ httpreferer }}">{{ httpreferer }}</a></td></tr>
            <tr><th>HTTP Method</th><td>{{ httpmethod }}</td></tr>
          </tbody>
        </table>
        {% endif %}

        <footer>
          <p>This form submission tool is only for use by current students in <a href="https://cscie12.dce.harvard.edu/">CSCI E-12</a> and <a href="https://cscis12.dce.harvard.edu/">CSCI S-12</a> courses.</p><p>David Heitmeyer | <a href="https://extension.harvard.edu/">Harvard Extension School</a> | <a href="https://summer.harvard.edu/">Harvard Summer School</a></footer>
      </body>
     </html>