This project is part of Harvard's CS50’s Web Programming with Python and JavaScript cours.
See https://cs50.harvard.edu/web/2020/projects/1/wiki/.
This program is a small-scale wiki, in which some programming languages and frameworks are defined.
Run python manage.py runserver inside the root directory of the project in your terminal. Follow the instructions in your terminal to run the according website in your browser or to stop the project.
On the index page you see a navigation bar to the left with Wiki as title. On the right you see a list of all entries in alphabetical order, that redirect you to an according entry if clicked on them.
Type a search request in the search bar to get redirected to an entry with the same title as the request. If the search request doesn't match an entry title, you get redirected to a search page with a list of all entries, that have the search request in their title and redirect you to that entry if clicked on them. Click on Home to get redirected to the index page.
On an entry page, you cann see the entire entry as text. Click on Edit to get redirected to an edit page for that entry. On the edit page you can edit the title of the entry and its content text. The content text must be written in Markdown format. Click on Edit to save the changes. If the edit was successfull, you'll be redirected to the edited entry page. If the edit wasn't successfull, you'll be redirected to an edit page with the original content.
Click on Create New Page to get redirected to an creation page for a new entry. On the creation page you can enter the title of the entry and its content text. The content text must be written in Markdown format. Click on Create to save the new entry. If the creation was successfull, you'll be redirected to the created entry page. If the creation wasn't successfull, you'll be redirected to a blanc creation page.
Click on Random Page to get redirected to a random entry page.
- CSS 3 or higher
- HTML 5.2 or higher
- PyPI Django 4.2.3 or higher
- PyPI markdown2 2.4.10 or higher
- Python 3.11.3 or higher
The project is structured as follows:
- wiki (root directory of the entire project)
- encyclopedia (root directory of the application "encyclopedia")
- migrations ()
- __init__.py ()
- static (directory for the static files of the encyclopedia application)
- encyclopedia (subdirectory for the static files of the encyclopedia application)
- styles.css (styles for the encyclopedia application)
- encyclopedia (subdirectory for the static files of the encyclopedia application)
- templates (directory for the HTML templates of the encyclopedia application)
- encyclopedia (subdirectory for the HTML templates of the encyclopedia application)
- entry.html (HTML file template for the entries of the encyclopedia application)
- index.html (HTML file template for the start page of the encyclopedia application)
- layout.html (HTML file template layout for all pages of the encyclopedia application)
- unfound.html (HTML file template for unfound entries of the encyclopedia application)
- encyclopedia (subdirectory for the HTML templates of the encyclopedia application)
- __init__.py ()
- admin.py ()
- apps.py ()
- models.py ()
- test.py ()
- urls.py (Python file with URLs that can be visited inside the encyclopedia application and are leading to according "views")
- util.py (Python file with functions to interact with entries of the encyclopedia application)
- views.py (Python file with functions that return HTTP responses to visited URLs inside the encyclopedia application)
- migrations ()
- entries (directory for the entries of the encyclopedia application)
- CSS.md (Markdown file with entry for the CSS language)
- Django.md (Markdown file with entry for the Django framework)
- Git.md (Markdown file with entry for the Git language)
- HTML.md (Markdown file with entry for the HTML language)
- Python.md (Markdown file with entry for the Pythonlanguage)
- wiki (subdirectory of the project "wiki")
- __init__.py ()
- asgi.py ()
- settings.py (Python file with settings for wiki project)
- urls.py (Python file with URLs that can be visited inside the project and are leading to according "views")
- wsgi.py ()
- db.sqlite3 (database of the project)
- manage.py (controlls commands for the project)
- encyclopedia (root directory of the application "encyclopedia")
The assignment was defined as follows:
Getting Started
Download the distribution code from https://cdn.cs50.net/web/2020/spring/projects/1/wiki.zip and unzip it.Understanding
In the distribution code is a Django project calledwikithat contains a single app calledencyclopedia.First, open up
encyclopedia/urls.py, where the URL configuration for this app is defined. Notice that we’ve started you with a single default route that is associated with theviews.index function.Next, look atencyclopedia/util.py. You won’t need to change anything in this file, but notice that there are three functions that may prove useful for interacting with encyclopedia entries.list_entriesreturns a list of the names of all encyclopedia entries currently saved.save_entrywill save a new encyclopedia entry, given its title and some Markdown content.get_entrywill retrieve an encyclopedia entry by its title, returning its Markdown contents if the entry exists orNoneif the entry does not exist. Any of the views you write may use these functions to interact with encyclopedia entries.Each encyclopedia entry will be saved as a Markdown file inside of the
entries/directory. If you check there now, you’ll see we’ve pre-created a few sample entries. You’re welcome to add more!Now, let’s look at
encyclopedia/views.py. There’s just one view here now, theindexview. This view returns a templateencyclopedia/index.html, providing the template with a list of all of the entries in the encyclopedia (obtained by callingutil.list_entries, which we saw defined inutil.py).You can find the template by looking at
encyclopedia/templates/encyclopedia/index.html. This template inherits from a baselayout.htmlfile and specifies what the page’s title should be, and what should be in the body of the page: in this case, an unordered list of all of the entries in the encyclopedia.layout.html, meanwhile, defines the broader structure of the page: each page has a sidebar with a search field (that for now does nothing), a link to go home, and links (that don’t yet work) to create a new page or visit a random page.Specification
Complete the implementation of your Wiki encyclopedia. You must fulfill the following requirements:
- Entry Page: Visiting
/wiki/TITLE, whereTITLEis the title of an encyclopedia entry, should render a page that displays the contents of that encyclopedia entry.
- The view should get the content of the encyclopedia entry by calling the appropriate
utilfunction.- If an entry is requested that does not exist, the user should be presented with an error page indicating that their requested page was not found.
- If the entry does exist, the user should be presented with a page that displays the content of the entry. The title of the page should include the name of the entry.
- Index Page: Update
index.htmlsuch that, instead of merely listing the names of all pages in the encyclopedia, user can click on any entry name to be taken directly to that entry page.- Search: Allow the user to type a query into the search box in the sidebar to search for an encyclopedia entry.
- If the query matches the name of an encyclopedia entry, the user should be redirected to that entry’s page.
- If the query does not match the name of an encyclopedia entry, the user should instead be taken to a search results page that displays a list of all encyclopedia entries that have the query as a substring. For example, if the search query were
ytho, thenPythonshould appear in the search results.- Clicking on any of the entry names on the search results page should take the user to that entry’s page.
- New Page: Clicking “Create New Page” in the sidebar should take the user to a page where they can create a new encyclopedia entry.
- Users should be able to enter a title for the page and, in a textarea, should be able to enter the Markdown content for the page.
- Users should be able to click a button to save their new page.
- When the page is saved, if an encyclopedia entry already exists with the provided title, the user should be presented with an error message.
- Otherwise, the encyclopedia entry should be saved to disk, and the user should be taken to the new entry’s page.
- Edit Page: On each entry page, the user should be able to click a link to be taken to a page where the user can edit that entry’s Markdown content in a
textarea.
- The
textareashould be pre-populated with the existing Markdown content of the page. (i.e., the existing content should be the initialvalueof thetextarea).- The user should be able to click a button to save the changes made to the entry.
- Once the entry is saved, the user should be redirected back to that entry’s page.
- Random Page: Clicking “Random Page” in the sidebar should take user to a random encyclopedia entry.
- Markdown to HTML Conversion: On each entry’s page, any Markdown content in the entry file should be converted to HTML before being displayed to the user. You may use the python-markdown2 package to perform this conversion, installable via
pip3 install markdown2.
- Challenge for those more comfortable: If you’re feeling more comfortable, try implementing the Markdown to HTML conversion without using any external libraries, supporting headings, boldface text, unordered lists, links, and paragraphs. You may find using regular expressions in Python helpful.
Hints
By default, when substituting a value in a Django template, Django HTML-escapes the value to avoid outputting unintended HTML. If you want to allow for an HTML string to be outputted, you can do so with the safe filter (as by adding
|safeafter the variable name you’re substituting).
The following were changed in the distribution code:
- Inside
views.pyfile of the encyclopedia application: added theentry,edit,search,randomandcreatefunctions and theCreateEntryclass - Inside
views.pyfile of the encyclopedia application: imported themarkdown2,random,os.pathandosmodules - Inside
urls.pyfile of the encyclopedia application: added thepathfunctions with namesentry,edit,search,randomandcreateinside theurlpatternslist - Inside
urls.pyfile of the encyclopedia application: addedapp_namevariable with valueencyclopedia - Inside
layout.htmlfile in theencyclopediadirectory in thetemplatesdirectory of the encyclopedia application:- changed
hrefattribute ofaelement inside of firstdivelement inside ofdivelement with classsidebar col-lg-2 col-md-3to"{% url 'encyclopedia:index' %}" - changed
hrefattribute ofaelement inside of firstdivelement inside ofdivelement with classsidebar col-lg-2 col-md-3to"{% url 'encyclopedia:index' %}" - embedded value of third
divelement inside ofdivelement with classsidebar col-lg-2 col-md-3inaelement - embedded value of second
divelement inside ofdivelement with classsidebar col-lg-2 col-md-3inaelement
- changed
- Inside
index.htmlfile in theencyclopediadirectory in thetemplatesdirectory of the encyclopedia application: embedded value oflielement inside ofulelement in anaelement withhrefattribute and"{% url 'encyclopedia:entry' title=entry %}"as its value - Inside the
encyclopediadirectory in thetemplatesdirectory of the encyclopedia application: added theentry.html,unfound.html,results.html,create.html,edit.htmlandexists.htmlfiles - Inside the
style.cssfile in theencyclopediadirectory in thestaticdirectory of the encyclopedia application: deleted thetextareaselector and added the.edit_formselector - Inside the
util.pyfile inside the encyclopedia application: added akeyargument to thesortedfunction inside the argument of thelist_entriesfunction