lumeland / lume

🔥 Static site generator for Deno 🦕
https://lume.land
MIT License
1.75k stars 74 forks source link

Better path naming convension #605

Closed ngdangtu-vn closed 2 months ago

ngdangtu-vn commented 2 months ago

Enter your suggestions in details:

I stole the idea from here: https://start.solidjs.com/core-concepts/routing#renaming-index (Don't tell them ok?)

Let's get start with "Page Files":

OLD
.
├── index.md                                     => /index.html
└── posts                                        
    └── 2020-06-21_hello-world/                  
        └── index.md                             => /posts/hello-world/index.html
        └── other.md                             => /posts/hello-world/other/index.html

NEW
.
├── index.md                                     => /index.html
└── posts                                        
    └── 2020-06-21_hello-world/                  
        └── (hello-world).md                     => /posts/hello-world/index.html
        └── other.md                             => /posts/hello-world/other/index.html        

What's about "Shared Data"?

OLD
├── _data.yaml      # Data shared with all pages
├── index.md
└── documentation
    └── _data.json  # Shared with pages in this directory and subdirectories
    └── doc1.md
    └── doc2.md
    └── examples
        └── _data.json  # Shared with pages in this directory and subdirectories
        └── example1.md
        └── example2.md

NEW
├── _data.yaml      # Data shared with all pages
├── index.md
└── documentation
    └── _(documentation).json  # Shared with pages in this directory and subdirectories
    └── doc1.md
    └── doc2.md
    └── examples
        └── _(ex).json  # Shared with pages in this directory and subdirectories
        └── example1.md
        └── example2.md

Summary:

I don't want to use [] and {} yet because I'm not sure whether we will have any meta files in the future. How do you think?

oscarotero commented 2 months ago

Hmm, I don't think this proposal is better than the current one. For page files it introduces some inconsistencies:

For shared data, I think it's not very practical. You have to name the file like the folder but with parenthesis and underscore.

ngdangtu-vn commented 2 months ago

This is about naming convention. The main reason is to avoid a dozen index.md and _data.{ext}. It is truly a pain to me every time I try to do quick search or put 2 tabs side by side. So...

For shared data:

Naming Convention using bracket

Note This style detects special files by its pair of bracket. Any text inside the bracket is treated as comment to the users for the sake of searching files (or any activity that needs a good distinguishable name)

oscarotero commented 2 months ago

What I mean is, to specify a index page you can do this:

posts/
  index.md
  post1.md
  post2.md

But you can also do this:

posts.md
posts/
  post1.md
  post2.md

posts.md is saved as posts/index.html, so you don't need to create a index.md file in the source file.

According to your comment, I assume the content between parenthesis doesn't matter and /(foo).md and /(bar).md outputs the same file /index.html? To me is a bit confusing.

If you don't like to have _data.yml files everywhere, a solution is to create _data folders and place the data files inside. This would make them easily searchable. But having _(foo).yml and the foo part is not used anywhere, (even for the variable name) is confusing.

I guess it's a matter of taste. I didn't investigate but technically, it might be possible to create a plugin to use this convention. Lume uses a virtual filesystem (core/fs.ts) and a plugin could search for all entries and rename them ([hello-world].md to index.md and (hello-data).yml to _data.yml).

But implementing this behavior natively in Lume is too much. If you want to work on a plugin for that, I can help you.

ngdangtu-vn commented 2 months ago

Ok, if this can go with a plugin, then so be plugin. I'm not sure where to start though.

oscarotero commented 2 months ago

Thanks for understanding. I'll create an initial implementation and will let you know

oscarotero commented 2 months ago

@ngdangtu-vn I've created this code that does what you want:

site.addEventListener("afterLoad", () => {
  const fs = site.fs;

  for (const file of fs.entries.values()) {
    // Index files. E.g. `(foo).md` is renamed to `index.md`
    const isIndex = file.name.match(/^\([^)]+\)(\.\w+)$/);

    if (isIndex) {
      const [,ext] = isIndex;
      file.name = `index${ext}`;
      continue;
    }

    // Data files. E.g. `[foo].json` is renamed to `_data.json`
    const isData = file.name.match(/^\[[^\]]+\](\.\w+)$/);

    if (isData) {
      const [,ext] = isData;
      file.name = `_data${ext}`;
      continue;
    }
  }
})

It doesn't work in the stable version of Lume because it uses the afterLoad event that is not available yet. But you can use it in the latest development version (deno task lume upgrade --dev).

ngdangtu-vn commented 2 months ago

@ngdangtu-vn I've created this code that does what you want:

site.addEventListener("afterLoad", () => {
  const fs = site.fs;

  for (const file of fs.entries.values()) {
    // Index files. E.g. `(foo).md` is renamed to `index.md`
    const isIndex = file.name.match(/^\([^)]+\)(\.\w+)$/);

    if (isIndex) {
      const [,ext] = isIndex;
      file.name = `index${ext}`;
      continue;
    }

    // Data files. E.g. `[foo].json` is renamed to `_data.json`
    const isData = file.name.match(/^\[[^\]]+\](\.\w+)$/);

    if (isData) {
      const [,ext] = isData;
      file.name = `_data${ext}`;
      continue;
    }
  }
})

It doesn't work in the stable version of Lume because it uses the afterLoad event that is not available yet. But you can use it in the latest development version (deno task lume upgrade --dev).

Look neat, cool. I'll try it once I have time.

ngdangtu-vn commented 1 month ago

It works nicely with version 2.2.0