The navbar appears at the top of every page on the website. It is indicated in the drawing above and contains just a few menus, the search bar and the profile dropdown. In the menu admin database, the navbar must be named navbar, lower case.
The yearly menu bar (with yellow background above) appears on every page for a conference year with the exception of the virtual site. The yearly menubar must be named /Conferences/yyyy where yyyy is a year. This menubar will appear on every page with a path that starts with /Conferences/yyyy. The latest year's menubar will appear in places like /Careers where the path does not contain a year.
The virtual site has a different menubar that contains links to program content. A example virtual site yearly menu bar is down below. The virtual menubar needs to be named /virtual/yyyy where yyyy is a year.
The menu'ing system uses the standard Django admin interfaces, available at /admin/menus/menu/
In the screenshot above, you see a flat list of the top level menus: the single navbar, a yearly menu bar for each year, e.g. /Conferences/2021, and a virtual menubar for most years, e.g. /virtual/2023. There is a drag handle that is used to reorder menus and a disclosure triangle that collapses and shows nested menus. At the upper right is the “ADD MENU +” button. These will be the most common things you use when building or editing menus.
The screenshot above shows the menu form where you create or edit menus. These fields are required: Name, Parent, Template, Expand point. Link is optional and if a link is present, clicking the menu will follow the link. As mentioned above, the name field has some constraints: for a navbar, the name should be ‘navbar’. For a yearly menubar, it should be e.g. /Conferences/2023. For a virtual yearly menubar, it should be /virtual/2023. The template for both the virtual and main website yearly menubar is “yearly_menubar.html”. For Children of these menus, naming is not constrained. The name field is considered a safe_string and can accept tags. <strong>Calls</strong> is a valid name for a menu.
There are additional fields for more advanced menus that will be discussed below: style, classes, indent is_a_document, suppress lower divider, show_after and show_before.
Above, the Attend dropdown menu (part of the yearly menubar) is activated. Any menu item that will contain children is a “submenu” and is rendered using the “submenu.html” template. In the screenshot above, the “Attend” menu has the children “Child Care, Visiting New Orleans…” and so its template should be “submenu.html”.
The children under Attend do not, themselves, have children and their template should be ‘item.html’. Just to the left of the Attend menu is the “Conference Site” item. Similarly it has no children and its template should also be “item.html". The navbar can contain items too, but none are shown in this example.
Above is a screenshot of the NeurIPS Submit menus, which is a more complicated menu. In it, there is a header at the top of the menu, “Calls 2023” with items below it some of which are indented. All items in the dropdown were created with the “item.html” template. The Calls 2023 item at the top in the large font was created by adding "fw-bolder fs-4" to the classes field. These classes are provided by bootstrap. The indented and reduced font size of “Paper FAQ” in the above example is achieved by checking the “indent” field in the model form. By default, each “item” has a horizontal divider between it and other items, but in the example above the dividers are missing. To eliminate a divider, check “suppress divider below” on each item.
You may also apply styles using the style field. In the examples above, the NeurIPS yearly menubar have background-color: #FAFAC8; in the style field to give the menu its yellow background color. The virtual sites might have something like background-image: url(/static/virtual/img/navbackground.png); background-repeat: repeat-x; in their style field to give them a textured background to distinguish them from the yearly menubar.
The admin interface asked you to choose the parent of each item you're adding. Navbars and yearly bars do not have a parent. When there are lots of menus in the database, choosing a parent becomes difficult. If a menu is not changing much, e.g. last year's virtual yearly menubar, you may archive it to the file system. Archiving it writes the file out as HTML, serializes it to YAML, and removes it from the database. If an HTML menu is detected on the filesystem, it's used rather than building the menu from the menus in the database. This improves performance and removes older menus as parent choices. Archives are stored in menus/templates/shared/{database} where {database} is something like nips, icml, or icli.
When working with a top-level menu (a navbar or yearly menubar), drag it to the top of the list in the admin interface to make choosing parents easier.
The admin menu appears on the navbar if you're logged in as an admin. Because this menu is shared across all conferences, it archives to menus/templates/shared. The admin menu was built in the NeurIPS (nips) database and it should only be unarchived, edited and rearchived on that database. The archived YAML refers to specific menu database primary keys and will cause problems if it is unarchived to a database different database than the one that created it.
To update the menu on in production simply edit the menus in the database on your development server in the admin interface. After you've made and tested the changes go to back to the admin interface for Menus, select the Admin database instance and choose action “Archive ADMIN menu to shared folder." This action will update file “menus/templates/menus/shared/admin.html” that you should commit that to git and then deploy as normal.
The command ./manage.py test-menus will recurse through the links in Menu.objects and load each page as an Admin, a standard user and as an anonymous user. If the page crashes, you'll see the traceback. If the page has incorrect permissions, you'll see a warning.
If a page should have admin permission, then it should return a 403 status code or it should return a redirect to login as admin with a 307 status code. A page will be assumed to need an admin (superuser) if it has “admin” or “Admin” in its path. If a page should be restricted to superusers but doesn't have admin or Admin in the path, then add its path to test-menu-links.py to the “expected_return_codes” dictionary following the pattern described in the source code.
If a page requires a standard login, e.g. MyStuff, then you'll get a 200 status code for superuser and a 200 code for a standard user and a 307 for an anonymous user.
The first time you run ./manage.py test-menu-links, it may take awhile because it will test every link in every menu. NeurIPS has over 400 links to test. At the end of the run, any page that was determined to load correctly will be added to a pickle file called ok_pages.pickle. The next time you run ./manage.py test-menu-links, you will be given a change to skip any page that was found to be okay in the previous run. This way you can fix issues and re-run the test more quickly. Do not commit ok_pages.pickle to the repository.