Project 2 — Dynamically Generated Content

CS-332: Web Programming

Fall 2021

For the duration of this course, you will work in teams to develop a microblogging and social networking web application based loosely around Twitter. In this second project, you will work individually to add dynamic content to your user interface from Project 1. You will gain experience programming in JavaScript, manipulating the DOM, and using asynchronous fetch.

SlugFest is said to be the next hit social media site1—you just have to create it first! Members can post short messages ("slimes") for their followers to read. Members can also "favorite" slimes that they like or even "reslime" so that the post shows up on their own profile. Additionally, this is a social site, so it is possible to reply to slimes creating a "slime trail" conversation. If these features sound familiar, that's because they are based off of those supported by a popular microblogging and social media site.

You will be given a collection of JSON files containing the information for SlugFest to display. It is your job to recreate many of the pages from Project 1 using this information.

Requirements

Working individually, create a collection of HTML and JavaScript files that:
  • Uses Bootstrap 5 for styling
  • Implements the following pages:
    • a "home" feed page,
    • profile pages for four users (Kevin Angstadt, Ed Harcourt, Choong-Soo Lee, and Lisa Torrey),
    • a "slime trail" page showing the slime with ID 611fcaf640148d94e2a469c7 and its replies, and
    • a notification page
  • Uses JavaScript to dynamically display slime and user information on each of the pages. That is, your HTML should not contain any of the content beyond the basic structure of each page.
    • There should only be one copy of the code for generating user profiles. Do not hard-code usernames into separate JavaScript files that are identical except for usernames!
    • There should only be one copy of the code for producing a slime in user profiles and the home feed. You may need different code on the slime trail page.
  • Closely matches the styling from Project 1
  • Supports navigation between the various pages
  • Displays well on desktops, laptops, and mobile devices

Assets

 Download p2_assets.zip

You are provided with the profile pictures for users of SlugFest. Additionally, there are JSON files in an API (Application Programming Interface) directory. These JSON files contain structured data representing each slime as well as each user account. Skeleton HTML files are also provided, should you wish to use them (you may also use your own code).

Thes files may be downloaded here. An older copy (with different user information) is available here. The contents of this file is:

              
                unzip -l p2_assets.zip 
                (out)Archive:  p2_assets.zip
                (out)Length      Date    Time    Name
                (out)---------  ---------- -----   ----
                (out)        0  10-26-2021 15:13   starter-code/
                (out)        0  10-26-2021 14:46   starter-code/skeletons/
                (out)     3809  10-26-2021 14:46   starter-code/skeletons/feed.html
                (out)     5615  10-26-2021 14:52   starter-code/skeletons/profile.html
                (out)     2940  10-26-2021 14:53   starter-code/skeletons/notifications.html
                (out)     3045  10-26-2021 14:52   starter-code/skeletons/slime.html
                (out)        0  10-26-2021 15:13   starter-code/api/
                (out)        0  10-26-2021 15:00   starter-code/api/favorites/
                (out)     1011  10-26-2021 15:00   starter-code/api/favorites/ltorrey.json
                (out)     2421  10-26-2021 15:00   starter-code/api/favorites/ed.json
                (out)     2118  10-26-2021 14:38   starter-code/api/favorites/list.json
                (out)        3  10-26-2021 14:59   starter-code/api/favorites/choongsool.json
                (out)     2118  10-26-2021 15:00   starter-code/api/favorites/kevinaangstadt.json
                (out)        0  10-26-2021 13:25   starter-code/api/user/
                (out)        0  10-26-2021 13:26   starter-code/api/user/get/
                (out)      570  10-26-2021 14:49   starter-code/api/user/get/ltorrey.json
                (out)      494  10-26-2021 14:49   starter-code/api/user/get/ed.json
                (out)      452  10-26-2021 14:49   starter-code/api/user/get/choongsool.json
                (out)      578  10-26-2021 14:48   starter-code/api/user/get/kevinaangstadt.json
                (out)        0  10-26-2021 15:13   starter-code/api/statuses/
                (out)        0  10-26-2021 15:13   starter-code/api/statuses/replies/
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175ccd3969d515951edefac.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175cb4a969d515951edefa9.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175ccf1969d515951edefaf.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175ca7a969d515951edefa7.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175ccbe969d515951edefaa.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175ccfa969d515951edefb0.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175ccde969d515951edefad.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175cce8969d515951edefae.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175ccc7969d515951edefab.json
                (out)     1147  10-26-2021 14:36   starter-code/api/statuses/replies/611fcaf640148d94e2a469c7.json
                (out)     1278  10-26-2021 14:36   starter-code/api/statuses/replies/6175c92c969d515951edefa3.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175c9a2969d515951edefa4.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175cb11969d515951edefa8.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175c9e3969d515951edefa5.json
                (out)        3  10-26-2021 14:36   starter-code/api/statuses/replies/6175ca53969d515951edefa6.json
                (out)        0  10-26-2021 14:18   starter-code/api/statuses/show/
                (out)      884  10-26-2021 14:18   starter-code/api/statuses/show/6175ccd3969d515951edefac.json
                (out)     1192  10-26-2021 14:18   starter-code/api/statuses/show/6175cb4a969d515951edefa9.json
                (out)      885  10-26-2021 14:18   starter-code/api/statuses/show/6175ccf1969d515951edefaf.json
                (out)     1973  10-26-2021 14:18   starter-code/api/statuses/show/6175ca7a969d515951edefa7.json
                (out)      884  10-26-2021 14:18   starter-code/api/statuses/show/6175ccbe969d515951edefaa.json
                (out)      884  10-26-2021 14:18   starter-code/api/statuses/show/6175ccfa969d515951edefb0.json
                (out)      885  10-26-2021 14:18   starter-code/api/statuses/show/6175ccde969d515951edefad.json
                (out)      884  10-26-2021 14:18   starter-code/api/statuses/show/6175cce8969d515951edefae.json
                (out)      885  10-26-2021 14:18   starter-code/api/statuses/show/6175ccc7969d515951edefab.json
                (out)     1028  10-26-2021 14:18   starter-code/api/statuses/show/611fcaf640148d94e2a469c7.json
                (out)     1063  10-26-2021 14:18   starter-code/api/statuses/show/6175c92c969d515951edefa3.json
                (out)     1890  10-26-2021 14:18   starter-code/api/statuses/show/6175c9a2969d515951edefa4.json
                (out)     2022  10-26-2021 14:18   starter-code/api/statuses/show/6175cb11969d515951edefa8.json
                (out)      935  10-26-2021 14:18   starter-code/api/statuses/show/6175c9e3969d515951edefa5.json
                (out)     1064  10-26-2021 14:18   starter-code/api/statuses/show/6175ca53969d515951edefa6.json
                (out)        0  10-26-2021 13:30   starter-code/api/statuses/user_timeline/
                (out)     3348  10-26-2021 13:30   starter-code/api/statuses/user_timeline/ltorrey.json
                (out)     4317  10-26-2021 13:30   starter-code/api/statuses/user_timeline/ed.json
                (out)     7006  10-26-2021 13:30   starter-code/api/statuses/user_timeline/choongsool.json
                (out)     4683  10-26-2021 13:29   starter-code/api/statuses/user_timeline/kevinaangstadt.json
                (out)     5418  10-26-2021 13:25   starter-code/api/statuses/activity.json
                (out)    19345  10-26-2021 13:24   starter-code/api/statuses/home_timeline.json
                (out)        0  10-26-2021 15:13   starter-code/assets/
                (out)        0  10-11-2021 13:27   starter-code/assets/profile/
                (out)   249750  09-05-2021 14:17   starter-code/assets/profile/kevin.jpeg
                (out)    79031  09-05-2021 14:20   starter-code/assets/profile/choong-soo.png
                (out)    75662  09-05-2021 14:17   starter-code/assets/profile/ed.png
                (out)    18900  09-05-2021 14:18   starter-code/assets/profile/lisa.jpeg
                (out)---------                     -------
                (out)   512456                     65 files
              

            

Commentary

As befitting a 300-level elective, this assignment is fairly open-ended. There is no "one true path" to creating and styling the required pages. Thus, this project requires you to tap your inner creativity and problem-solving.

Under-specification is fairly indicative of the real world. Clients will often expect you to "read their mind" to deliver a product that meets their needs. This can definitely be frustrating at times, but it is also a good lesson to learn early. It will help you be a high-quality developer who gains a positive reputation with clients.

A keen eye for detail is also key here. While there is textual description of each page provided, taking a close look at the provided images for styling and inferring withheld information can help you decide how to proceed.

As this is an upper-level course, you may use outside references to complete this assignment. Be sure to keep a running list of citations as you work on this project.

DANGER! This is a typical warning, but do not wait to get started on this project. Front load the work so that you are not scrambling to finish.

Recommended Approach

You will most certainly want to split your code into multiple JavaScript files. A good first step is to create a file for generating the HTML needed to display slimes. Note that you may need separate functions for slimes on "standard" pages vs. the "slime trail" page. One possible function interface is shown below.

              
                /**
                 * Create a Slime DOM and return it
                 * @param slimeData {object} all of the data needed to create a slime 
                 * @return a DOM Element object for the slime 
                 */
                function createSlime(slimeData) {

                }
              
            

There are many opportunities for code reuse across this project. One such place is for generating user profile pages. Thus, only write this code once. Write this code as a function that receives a username as a parameter so that it can be used for all profile pages. Then, have a small piece of JavaScript on each individual user profile page that calls this function with the appropriate username after the page has loaded.

To assist your code reuse, avoid the temptation of combining code to process and manipulate JSON data with code to produce and manipluate DOM nodes. This can be very tempting, but it reduces your ability to reuse code. Write some functions that fetch and process JSON to produce JavaScript objects. Write different functions that take an object and produce a DOM node. You might even consider writing separate functions that take DOM nodes and insert them at specific selectors on a page.

Be sure to ask lots of questions as you work on this project. Questions about the desired behavior are likely to receive more expressive answers than direct questions about the reference implementation (your clients won't have a reference impelmentation).

Because there will be a nontrivial amount of code for this project, make a separate folder to hold all of this code. Typically, this folder will be named js.

You may want to look back at the Project 1 specification for styling hints.

What to Submit for P2

Be sure that you are submitting to the correct assignment on Gradescope! Further, be sure to make sure that you submit all required files. Don't wait until the last minute to submit (you can resubmit up to the deadline).

Submit the following:

  • *.html: all HTML files needed for your pages
  • *.js: all JavaScript files needed for your pages
  • *.css: any additional CSS files you may have needed.
  • All asset files used in your project (e.g., profile images, JSON)
  • An HTML or TXT file containing a list of citations for resources you used to complete this project. No specific convention is required, but this list should provide sufficient information to find a copy of each resource.

I will view your files by creating a small Python webserver as we have done in class:

              
                python3 -m http.server
              
            

Thus, make sure that your files are submitted with a folder structure identical to your development machine. You will likely want to use relative URIs for assets.

Grading Rubric

P2 Grading (out of 100 points):

  • 35 points: Webpage content
    • Each of the required pages is worth 5 points
    • To receive all five points per page, ensure that all content is generated for each page and that each page functions as expected.
  • 55 points: JavaScript Implementation
    • You will be graded on your proper use of JavaScript, including:
      • Use of the fetch API
      • Higher-order functions
      • Asynchronous programming (Promises, Callbacks, async/await)
      • Proper use of event handlers
    • You will receive more points for increased use of good coding habits. Such habits include:
      • Splitting out DOM manipulation from data manipulation
      • Reducing code reuse by placing common code in functions
      • Splitting JavaScript into several files to facilitate use across pages
      • Minimizing the number of global bindings (variables) created in your code
  • 5 points: Formatting of HTML and JavaScript
    • 5 — files are well-formatted (proper indentation, no extremely long lines, etc.)
    • 3 — files are generally well-written, but spacing is not uniform (e.g., large gaps, old commented code, etc.).
    • 1 — files are very difficult to follow and contain the bare minimum of formatting.
    • 0 — script contains no comments.
  • 5 points: References
    • 5 — Standalone references file exists and contains a list of resources used for this assignment. This includes course materials.
    • 2 — References file exists, but might not be separate, is the wrong format, or does not adequately identify resources used for this assignment.
    • 0 — No references file provided.

Relevant API JSON Data

Below is a description of some of the API data provided in the assets for this project. Note that you will likely have to look through this data in more detail, but use this as a starting place for finding the right files.

As a side note, this JSON file structure is based very closely on the Twitter v1.1 API to give you a real sense of implementing a real-world application. Some aspects of the file layout have been modified to work better with this project.

Favorites

Lists of each user's favorited slimes are stored in /api/favorites/<username>.json. These are sorted in reverse order (with the newest first). Note that the associated slime IDs are also available through the User API for individual access through the Statuses API.

Users

Information about each user is provided in /api/user/get/<username>.json. These JSON files contain information about each user account on SlugFest.

Statuses

The statuses API provides information about status updates (aka slimes). There are several relevant pieces, ranging from timelines to individual slimes.

Timelines

Timelines (sorted lists of slimes) for each user are provided in /api/statuses/user_timeline/<username>.json.

The main timlines (the home feed page) is provided in /api/statues/home_timeline.json

Individual Slimes

Individual slimes are available in /api/statuses/show/<slime_id>.json. A slime ID is a unique string associated with each slime when it is posted.

It is also possible to see the slimes that are in reply to another slime. This information is stored in /api/statuses/replies/<slime_id>.json, where a slime ID is defined as above.

Slime Activity

Slime activity (aka notifications) are stored in /api/statuses/activity.json. To simplify coding, this will only show reslimes and replies (we are dropping favorites from notifications).

Acknowledgements

The initial concept for this project is borrowed from an assignment designed by Andrew DeOrio at the University of Michigan.

1By your professor