.. _page-navigation: Page Navigation =============== So far, we've used the address bar in the browser to access each webpage we've built. However, we need to do better than this. Users shouldn't have to type in the address for every page they want to visit! Adding links that connect to other pages in our website makes navigation much easier. These links can take many forms, like a simple list of URLs, a set of clickable icons, *Next Page* and *Previous Page* buttons, a dropdown menu, or a nav bar. (You can find several of these options on this page!) A List of Links --------------- Let's start with a basic, unordered list of links. Each item will lead to one of the pages in our website. For now, we will keep the design simple. We can make it look nice after we get the navigation working. Since we want the list to appear on every page, we will add it to the base template. #. Open ``base.html`` in Visual Studio Code. #. Add a ``nav`` element below the ``endblock`` statement. Include a heading and an unordered list. Make one item for each of the pages you created earlier. .. sourcecode:: html :lineno-start: 15 Save your work, then launch ``main.py``. The list should appear on each page that extends ``base.html``. #. Next, change the list items from text to active links. a. Wrap the text in link tags, ````. .. sourcecode:: html
  • Pizza Topping Form
  • Second Page
  • b. Fill in the ``href`` values with the path to each page: .. sourcecode:: html
  • Pizza Topping Form
  • Second Page
  • Note the values assigned to each ``href``. The strings *match the paths* from the ``@app.route()`` handlers in ``main.py``. They should NOT be the ``.html`` names you gave to the template files. The paths you use will depend on your Python code. They might not match this example. #. Save your work, then refresh the tab in the browser. Properly done, the navigation links should work something like this: .. figure:: figures/basic-nav.gif :alt: Clicking either of the two links in the list navigates to the chosen page. A list of links provides basic website navigation. .. admonition:: Try It! If we hover the pointer over one of the links, its URL appears in the bottom corner of the browser window. .. figure:: figures/link-url.png :alt: Hovering over a link displays the target URL in the lower corner of the browser window. Bring in Some Logic ------------------- So far, so good. The list of links works. However, there is a weakness in our code. If we add, remove, or rearrange the pages in our website, we need to manually adjust the ``li`` elements in ``base.html``. It would be better if the size and order of the list automatically updates when we make a change. Fortunately, we make this happen by adding a ``for`` loop to the base template. Since each link requires two pieces of data (an ``href`` value and the link text), we have a few options for feeding this information from Python to the templates. Three possibilities are a list of lists, a dictionary, or an object created from a user-defined class. (There are other choices as well). In this case, we will use a dictionary. Update ``main.py`` ^^^^^^^^^^^^^^^^^^ #. Near the top of the code in ``main.py``, define a dictionary called ``navigation``. #. Add one key/value pair for each page in your website. The *key* will be the text for the link. The *value* will be the path to that page. .. sourcecode:: Python :lineno-start: 3 app = Flask(__name__) app.config['DEBUG'] = True navigation = { 'Pizza Toppings Form': '/', 'Second Page': '/second' } #. Include the ``navigation`` dictionary as an argument in each ``render_template()`` function. .. sourcecode:: Python return render_template('template_name', navigation = navigation, ...) .. _jinja3-dictionary-iteration: Update ``base.html`` ^^^^^^^^^^^^^^^^^^^^ Jinja3 uses the same syntax as Python to loop through a dictionary :ref:`by key/value paris `. #. Replace the ``li`` items in the list with a loop: .. sourcecode:: html :lineno-start: 15 #. Each time the loops runs, ``text`` is assigned the next key in the dictionary. ``path`` takes the value of that key. #. Save your work, then refresh the tab in the browser. Test to make sure both links still work. .. admonition:: Try It! With the loop in place, changes made to ``navigation`` will appear on all pages that extend ``base.html``. Test this out! #. Try rearranging the order of the key/value pairs in ``navigation``. #. Add a third page to the website. Include a key/value pair for the page in the ``navigation`` dictionary. A Dropdown Menu --------------- As a website grows, the navigation menu requires more space on the page. To keep their layout neat and consistent, web developers often use features that hide the menu until a user reveals it. .. figure:: figures/dropdown-menu.png :alt: A dropdown menu appears when the cursor hovers over a heading. :width: 80% Menu items appear when the user hovers over a each heading. While it won't be as fancy as the image, we can add some CSS rules to make our own dropdown menu. It will appear when the user moves their pointer over the ``Page Navigation`` heading. #. First, add the following ``class`` attributes to the ``