jannikbuschke / gatsby-antd-docs

A gatsby starter for a technical documentation website
https://www.jannikbuschke.de/gatsby-antd-docs/
MIT License
68 stars 21 forks source link

Specify custom order for sidebar #1

Open GordonSmith opened 5 years ago

GordonSmith commented 5 years ago

Is there anyway to specify the order of the sidebar items?

Currently the only way I seem to be able to do this is to:

Looks like the above does not work when the site is pushed to gh-pages...

wagnerjt commented 5 years ago

Hey Gordon, I just found this repo today actually and want to contribute some items I am going to run into digging through it, and this is one of them. Can you help me understand if you need to sort the children in some order you choose, or is the children okay to remain sorted in alphabetical order based on the the markdown Metadata title?

GordonSmith commented 5 years ago

I would want to sort both the headers and children in a specific order, My instinct was to look for a "index" item in the markdown header section...

jannikbuschke commented 5 years ago

Yes this feature I also need myself. I will probably have a bit of time in the upcoming weeks, but cannot promise anything yet.

Feel free to open PRs. An index property on frontmatter/markdown sounds reasonable to me.

wagnerjt commented 5 years ago

Hmm. It might be too troublesome for maintaining and updating your indices if the sorting index is tucked away in the markdown's Metadata. I can just imagine someone having even 7 children under a parent, and creating a new child for index 2. It'd be a pain to fish and do a +1 to all the following markdown files.

I was thinking about a simple js object, where the parent's name is the key, and the children is an array, listed in order for the sidebar. When the template gets generated, we can combine this object and the graphql response to perform the ordering, defaulting to alphabetic if there is none.

Thoughts?

GordonSmith commented 5 years ago

I don't have strong feelings on it, but one comment about the index suggestion is that you don't need to do sequential numbers, IOW: 100, 200, 300 would work equally well (and leave you plenty of room to insert a new one quickly...)

But your suggestion would also open the door to having the same solution for the main (parent) items?

mrpotatoes commented 5 years ago

I put this in my version. To note mine is much more organized but I'm just giving the code. What I like about this version is that it's

  1. Based on a new property not text manipulation.
  2. Based on a weight not an exact ordering. I order from 100 to 1 with 100 being the first. I may change my version to be backwards as I reason it better as ascending vs descending.
  3. If the numbers are the same nothing breaks. If an order doesn't exist it doesn't break.

In any of your slugs in your markdown add an order to your slug (requires a server restart)

---
title: Intro
root: '/docs'
parents: ['Farming']
order: 100
---

In SidebarContents.jsx change this

// Add this function somewhere
const orderComparator = (menuA, menuB) => {
  let comparison = 0;
  if (menuA.order > menuB.order) {
    comparison = -1;
  } else if (menuA.order < menuB.order) {
    comparison = 1;
  }

  return comparison;
}

// Where the children are being sorted change it to this
item.children.sort(orderComparator)

Finally in the same file change convertToTree to this:

const convertToTree = data => (
  constructTree(data.map(edge => ({
    path: edge.node.fields.slug,
    key: edge.node.id,
    title: edge.node.frontmatter.title,
    parents: edge.node.frontmatter.parents,
    order: edge.node.frontmatter.order || 0,
  })))
)
mrpotatoes commented 5 years ago

I also have ordering for the parents but I'm not a fan of how I'm doing that. I can give my code on that too but I think I will wait to see what comes of this repo next. I think it would actually be easier once the Gatsby version is updated. Cuz then we get the explorer tab in the graphiql explorer.

wagnerjt commented 5 years ago

I've been thinking, about my path. And ultimately, I only have needs for a 1:1 mapping between Parent and Child.

With that in mind, the path I'll take will remove the parents metadata from within the markdown, and derive this based upon the directory structure of the markdown contents. Also, the constructTree will have to be changed to do parent if directory, and child if some file.

An example would look like the following (after in some root like the docs).

docs
├── get-started
│   ├──  introduction.md
│   ├──  MDX.mdx
│   └── *.md|x
└── guide
    ├── anchor.mdx

Then have a plain object with defined ordering.

const parentMap = {
    INTRO: { dir: 'get-started', name: 'Introduction' },
    GUIDE: { dir: 'guide', name: 'Guide' },
};

const childMap = {
   [parent.INTRO.dir]: {
      'introduction',
      'mdx',
      '....',  
   },
};

Ordering occurs such that we loop over the parent and for each parent key, map into the children in this list. Of course, the default sort behavior, if you didn't include a child or parent, would be to sort by this first, then apply alphabetical ordering to them.

Pros:

Cons:

jannikbuschke commented 5 years ago

Why not make the children part of the parent structure directly? Something like

navigation = [
{
  dir: 'parent',
  displayName: 'Introduction', 
  children: [ ... ]
]