Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: tree generation for autogenerated groups #1151

Merged
merged 19 commits into from
Jan 18, 2024
Merged

fix: tree generation for autogenerated groups #1151

merged 19 commits into from
Jan 18, 2024

Conversation

kevinzunigacuellar
Copy link
Sponsor Member

@kevinzunigacuellar kevinzunigacuellar commented Nov 25, 2023

Description

  • Closes support for directory index pages #370
  • This PR modifies treeify() to build the file tree depth first. This way if a file and a directory in within the same level have the same name, the file is included into the directory and renamed to index.

Before

reference
 |- foo.md
 |- foo
     |- bar.md

After

reference
 |- foo
     |- bar.md
     |- index.md

Copy link

changeset-bot bot commented Nov 25, 2023

🦋 Changeset detected

Latest commit: edc95e1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@astrojs/starlight Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

vercel bot commented Nov 25, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
starlight ✅ Ready (Inspect) Visit Preview Jan 18, 2024 5:26pm
1 Ignored Deployment
Name Status Preview Updated (UTC)
starlight-i18n ⬜️ Ignored (Inspect) Visit Preview Jan 18, 2024 5:26pm

@github-actions github-actions bot added the 🌟 core Changes to Starlight’s main package label Nov 25, 2023
@astrobot-houston
Copy link
Collaborator

astrobot-houston commented Nov 25, 2023

size-limit report 📦

Path Size
/index.html 5.21 KB (0%)
/_astro/*.js 21.42 KB (0%)
/_astro/*.css 13.15 KB (0%)

@HiDeoo
Copy link
Member

HiDeoo commented Dec 18, 2023

I did not review the code in details yet altho I noticed a few sorting details that look weird to me when playing with the changes locally. The documentation says:

Autogenerated sidebar groups are sorted by filename alphabetically. For example, a page generated from astro.md would appear above the page for starlight.md.

Considering the existing file structure for the reference docs:

- src/
  - content/
    - docs/
      - reference/
        - configuration.md
        - frontmatter.md
        - overrides.md
        - plugins.md

I get the following sidebar for the reference folder:

- Configuration Reference
- Frontmatter Reference
- Overrides Reference
- Plugins Reference

If I add a docs/src/content/docs/reference/frontmatter/a.md file, I get the following sidebar:

- frontmatter
  - Frontmatter Reference
  - A test
- Configuration Reference
- Overrides Reference
- Plugins Reference

The 2 things that look weird to me are (and I'm not sure if they are related):

  • In the frontmatter folder, I think A test should be above Frontmatter Reference (because of the alphabetical order mentioned in the docs)
  • In the root reference folder, I think frontmatter should be below Configuration Reference right?

@kevinzunigacuellar
Copy link
Sponsor Member Author

kevinzunigacuellar commented Dec 18, 2023

Thank you for the kind review @HiDeoo! While examining the implementation, it seems that this bug is not related to the tree generation, however it is currently in production.

return collator.compare(isDir(a) ? keyA : a.slug, isDir(b) ? keyB : b.slug);

I think we meant to sort using the data.title of the file instead of the slug. That's why frontmatter is at the top because it is compared to reference/configuration instead of just Frontmatter Reference. I will follow up with another PR.

This bug also explains why A test is not at the top of frontmatter.

@HiDeoo
Copy link
Member

HiDeoo commented Dec 19, 2023

I think we meant to sort using the data.title of the file instead of the slug.

I'm not sure about this one, as the docs says:

Autogenerated sidebar groups are sorted by filename alphabetically.

So it should clearly be the file or directory name and not the title, right?

I based my two observations on this as:

  • A test is the title of the file a.md so should be before frontmatter.md (I could have use Zzzzz for the title to make it more obvious)
  • A frontmatter directory should be after a file named configuration.md

@delucis
Copy link
Member

delucis commented Jan 9, 2024

Oops! Looks like stuff broke when I updated branch. Can you take a look @kevinzunigacuellar?

@kevinzunigacuellar
Copy link
Sponsor Member Author

Fixed! it seem to be missing an import for basename. Also I had to update the test snapshot. It is correctly sorted now.

Copy link
Member

@delucis delucis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for getting into this gnarly logic @kevinzunigacuellar! Left a few comments.

Comment on lines 100 to 107
{
"attrs": {},
"badge": undefined,
"href": "/reference/frontmatter/",
"isCurrent": false,
"label": "Frontmatter Reference",
"type": "link",
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this item show first like it would if created via reference/frontmatter/index.md?

Not super simple to solve at first glance: our getComparisonId() helper added in #1298 doesn’t know if a file is a directory index, so reference/frontmatter.md is not treated the same as reference/frontmatter/index.md (the first returns 'frontmatter', the latter '').

I’m indecisive on whether it’s better to use an extra property on Route, e.g. sortId or something that we add, so a route could look like { id: 'reference/frontmatter.md', sortId: 'reference/frontmatter/index.md' }, OR whether our sorting logic should use a heuristic when comparing, e.g. when comparing 'reference/frontmatter.md' and 'reference/frontmatter/foo.md', turn the former into '' because it matches the directory (e.g. if stripExtension(idA) === dirname(idB), idA is an index).

Setting a sortId early would avoid those extra checks, so might be cleanest, even if it does add another property (we’d now have id, sortId, and entry.id). Doing it when sorting (I just tried 😁) is pretty gross.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch! Perhaps this sorting id could be generated when creating the tree. Everytime we go into a tree node recursively we could attach the current object property as a path. This way not only files but directories can also have a sorting id.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do directories need them? It’s only for this one case I think. But yeah, I think doing it then makes sense!

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it could make a more homogeneous comparison. Since it was not possible to know the directory path, comparisons between directories and files were done by comparing a filename and directory name. But if both were in include their paths it would make a bit easier.

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought I think It would be a better solution to include a slug property in directories dir["_slug"] since index pages defined as index or pages of the parent directory share the same slug.

Route slug
reference/frontmatter.md reference/frontmatter
reference/frontmatter/index.md reference/frontmatter

Then sorting by slug would be very trivial for both directories and files

Order Route/Dir slug (use this to sort)
1 reference/frontmatter/index.md reference/frontmatter
2 reference/frontmatter/bar reference/frontmatter/bar
3 reference/frontmatter/bar/foo.md reference/frontmatter/bar/foo
4 reference/frontmatter/fiz reference/frontmatter/fiz
5 reference/frontmatter/fiz/zoo.md reference/frontmatter/fiz/zoo
6 reference/frontmatter/foo.md reference/frontmatter/foo

Sidebar view

 reference/
    ├── index.md
    ├── bar/
    │   └── foo.md
    ├── fiz/
    │   └── zoo.md
    └── foo.md

This way index are always at the top, even in nested directories.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe? Not opposed to trying!

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in f4ee4ed, I need some help with types but everything seem to be working

packages/starlight/utils/navigation.ts Outdated Show resolved Hide resolved
packages/starlight/utils/navigation.ts Outdated Show resolved Hide resolved
packages/starlight/utils/navigation.ts Outdated Show resolved Hide resolved
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
Copy link
Member

@delucis delucis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinzunigacuellar I pushed a fix for the type issue in dc2292a!

To describe what was happening: the _slug property you tried adding collided with the generic [item: string]: Dir | Route. Trying to set an additional property with a string index was an error, because all string-indexable properties are declared to be Dir or Route, not string.

Instead, I followed the same pattern as we do for the DirKey: create a Symbol to index with, which we can then use to look up the value.

Also took the liberty of fleshing out the changeset and bumping this up to a minor just in case it has some unexpected side effect (I don’t think it should though).

Should be good to go! I will merge when we’re ready to ship the next minor. Thanks again for the dedication figuring out all the tricky corners of this one 💖

@delucis delucis added the 🌟 minor Change that triggers a minor release label Jan 16, 2024
@kevinzunigacuellar
Copy link
Sponsor Member Author

Nice refactor, thanks for polishing the final details of the implementation.

Self LGTM! 😆

@delucis delucis merged commit 134292d into main Jan 18, 2024
9 checks passed
@delucis delucis deleted the fix-dir branch January 18, 2024 17:27
@astrobot-houston astrobot-houston mentioned this pull request Jan 18, 2024
HiDeoo added a commit to HiDeoo/starlight that referenced this pull request Jan 23, 2024
* main: (23 commits)
  i18n(ko-KR): add`plugins.mdx` (withastro#1401)
  [ci] format
  i18n(ko-KR): add `community-content.mdx` (withastro#1402)
  i18n(ko-KR): update `site-search.mdx` (withastro#1400)
  i18n(ko-KR): add `showcase.mdx` (withastro#1403)
  [docs] new Resources sidebar section and pages (withastro#1357)
  i18n(hi): add `i18n.mdx` (withastro#1388)
  [ci] format
  [ci] release (withastro#1384)
  Restore original tighter line-height on `<LinkCard>` titles (withastro#1386)
  Refactor virtual module system for layout components (withastro#1383)
  Update astro to 4.2.1 (withastro#1385)
  fix: tree generation for autogenerated groups (withastro#1151)
  Tweak vertical spacing in Markdown content styles (withastro#1376)
  Update ToC highlighting styles to prevent UI shifts (withastro#1372)
  i18n(hi): update `index.mdx` (withastro#1380)
  [ci] format
  [ci] release (withastro#1379)
  Update dependencies (withastro#1378)
  [ci] format
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🌟 core Changes to Starlight’s main package 🌟 minor Change that triggers a minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support for directory index pages
4 participants