Nodejs.dev: Navigation / Section Proposal

Created on 3 Mar 2019  路  4Comments  路  Source: nodejs/nodejs.dev

Hi all,

as mentioned in the meeting the structure of our navigation will cause some headache, as soon as we intend to add new articles, change order or section of an Article. If you didn't notice that yet, take a look how we deal with navigation currently.

How do we do it now?

We make an allMarkdownRemark request to get all the documentations and sort them ascendingly.

Since the documentation files are named sequentially sort does the trick and returns them in the right order.

0001-node-introduction
0002-node-history
0003-node-installation
...

Then we group them by the field section, which we get from frontmatter data.

...
sections: allMarkdownRemark(
sort: { fields: [fileAbsolutePath], order: ASC }
) {
group(field: frontmatter___section) {
...

Then we pass all the documentations data to findActive() to determine couple of things like activePage, previousPage, nextPage, navigationSection.

const { activePage, previousPage, nextPage, navigationSections } = findActive(
  data.sections.group,
  currentPage
);

In the findActive.js we iterate through the edges and determine in a hacky way whether the node belongs to it's in MD file specified section or to Getting Started.

 const title = fieldValue === 'undefined' ? 'Getting Started' : fieldValue;

I hope you saw already the problem we run into. If not imagine you want to add a new article between 0001-node-introduction and 0002-node-history. And good luck with renaming the following dozen of files :]

There is a PR which improves determination of sections a bit, though improvement of a bad approach doesn't make the approach itself better :]

Better Approach

Here a quite flexible approach to organise navigation data: YAML!

Imagine having following YAML structure:

- title: Quick Start
  items:
    - title: Introduction to Node.js
      link: /learn/introduction-to-nodejs/
    - title: A brief history of Node.js
      link: /learn/a-brief-history-of-nodejs/
    - title: How to install Node.js
      link: /learn/how-to-install-nodejs/
- title: Getting Started
  items:
    - title: The V8 JavaScript Engine
      link: learn/the-v8-javascript-engine
    - title: Run Node.js scripts from the command line
      link: learn/run-nodejs-scripts-from-the-command-line

Why is that cool?

Because this approach is quite flexible, which makes it future-proof. We can move around articles, sections, play with order or link.

Imagine we need to introduce 3rd dimension in side navigation. With the actual structure we'd need to add a new field in all the articles and implement according logic in components. It's quite a bit tedious.

Though with YAML we need to just add whatever we need wherever we need (Assuming we have the logic in navigation component once):

- title: Quick Start
  items:
    - title: Introduction to Node.js
      link: /learn/introduction-to-nodejs/
    - title: A brief history of Node.js
      link: /learn/a-brief-history-of-nodejs/
    - title: How to install Node.js
      link: /learn/how-to-install-nodejs/
    - title: Magic behind Node.js
      link: /learn/magic-behind-nodejs/
      items:
        - title: How we treat our Unicorns
          link: /learn/how-we-treat-our-unicorns/
        - title: How we treat our Unicorns
          link: /learn/how-we-treat-our-unicorns/
- title: Getting Started
  items:
    - title: The V8 JavaScript Engine
      link: learn/the-v8-javascript-engine
    - title: Run Node.js scripts from the command line
      link: learn/run-nodejs-scripts-from-the-command-line

Or we can just link to another page, which is not even possible with our current codebase:

- title: Quick Start
  items:
    - title: Introduction to Node.js
      link: /learn/introduction-to-nodejs/
    - title: A brief history of Node.js
      link: /learn/a-brief-history-of-nodejs/
    - title: How to install Node.js
      link: /learn/how-to-install-nodejs/
    - title: Nodejs.org
      link: http://nodejs.org
- title: Getting Started
  items:
    - title: The V8 JavaScript Engine
      link: learn/the-v8-javascript-engine
    - title: Run Node.js scripts from the command line
      link: learn/run-nodejs-scripts-from-the-command-line

What about downsides?

Yes, there are few:

  • YAML / MD Synchronisation: We need to ensure that, fields that are used in both files are synchronised.
    Since we need to use createPage to provide static pages, we'll still need to keep the field title in MD files, so we can get it from GraphQL-Requests and pass to templates. This leads to the problem, -as long as we want to have same title on page and side navigation- that we have to make sure, that fields used in both files, must have the same value. A possible solution: We write a test, which iterates through the YAML file and checks if fields are equal in both files. Or we review carefully :]

  • YAML Files need to be generated manually: Yep, we can't really automatise them. A possible solution: Someone writes them :]

    Let me know if there is any room for improvements or if you have any concerns about this structure.

bug help wanted

Most helpful comment

Hi @ollelauribostrom we decided to postpone the implementation until we gain more experience what we exactly need also for another pages. :]

All 4 comments

Adding a YAML file would increase the bar of responsibility on each contributor. We all know how easy it is to mess up a YAML config file. I once managed a team of 40+ developers and anyone new with YAML files would mess up space or two at times to break things. Later we decided to move our config files to JSON for more strict and JS objects for less strict versions.

YAML file would have to be updated manually. Not sure if that's a good idea. I propose we keep using GraphQL and Gatsby's Node APIs to produce the navigation dynamically based on good architecture.

Instead of having 0001 based order, we can build folders for each category to keep the number of these folders small. Which would make it easier in case we'd need to add something in the mid?

Generally, I want the navigation to stay dynamic. We can introduce a priority and category frontmatter to deal with this. To place something in between 5th and 6th link, one could add `5.`` priority. Just an idea. Not sure though.

Ping! I'd like to raise that topic in the next meeting though some more opinions wouldn't be bad in advance :]

I wasn't able to attend the last meeting so not sure if this was discussed but I like the approach. With some extensive tests making sure that YAML and MD are synchronised I think we could mitigate some of the concerns raised by @ahmadawais 馃檪

Would probably be a good idea to run these tests in the pre-push hook, to remind the user to update the YAML file if necessary.

Hi @ollelauribostrom we decided to postpone the implementation until we gain more experience what we exactly need also for another pages. :]

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BeniCheni picture BeniCheni  路  4Comments

jemjam picture jemjam  路  3Comments

marcustisater picture marcustisater  路  3Comments

benhalverson picture benhalverson  路  4Comments

mmarchini picture mmarchini  路  4Comments