11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.

Home Page:https://www.11ty.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ability to add more pages on top of the input dir

Apostolique opened this issue · comments

Is your feature request related to a problem? Please describe.
Right now a configuration might look like this:

module.exports = function(eleventyConfig) {
  // Return your Object options:
  return {
    dir: {
      input: "docs",
      output: "dist"
    }
  }
};

Where the markdown files are picked up from the input dir.

The way I like to setup my files, I'd like this structure:

README.md
docs/
   Hello.md
.eleventy.js

Describe the solution you'd like
It could be possible for the input value to take an array:

module.exports = function(eleventyConfig) {
  // Return your Object options:
  return {
    dir: {
      input: ["docs", "README.md"],
      output: "dist"
    }
  }
};

Alternatively, there could be an API to programmatically add more page sources:

module.exports = function(eleventyConfig) {

  eleventyConfig.addPage('README.md')

  // Return your Object options:
  return {
    dir: {
      input: "docs",
      output: "dist"
    }
  }
};

The output folder would end up as:

dist/
   README/index.html
   Hello/index.html

Describe alternatives you've considered
Right now I have a script that copies the README.md into the docs folder.

Additional context
None

In an npm workspaces / lerna monorepo, I have 11ty files under /docs and packages under /elements and /core. I'd like to be able to include markdown templates in /{elements,core}/*/docs/index.md as well as assets at that dirname. My current solution involved copying those files over to /docs/components/$1:

plugin.cjs
const fs = require('fs');
const glob = require('glob');

const { basename } = require('path');

const getComponentName = path => {
  const [, , component] = path.match(/(elements|core)\/pfe-([-\w]+)\//) ?? [];
  return component;
};

function doCopy(path) {
  const component = getComponentName(path);
  if (component) {
    const copyTo = `docs/components/${component}/${basename(path)}`;

    // Check if the folder needs to be created
    fs.mkdirSync(`docs/components/${component}`, { recursive: true });

    // Copy the files for the component to the newly created folder
    fs.copyFileSync(path, copyTo);
  }
}

let didFirstBuild = false;

module.exports = {
  configFunction(eleventyConfig) {
    eleventyConfig.on('beforeBuild', () => {
      if (!didFirstBuild) {
        // Copy the assets for each component into the docs folder
        for (const path of glob.sync('{elements,core}/*/docs/*'))
          doCopy(path);

        didFirstBuild = true;
      }
    });

    eleventyConfig.on('beforeWatch', changed => {
      for (const path of changed)
        doCopy(path);
    });
  },
};

While this does work it's not ideal:

  • it doubles the work when saving a source file
  • it doubles the disk usage of docs files
  • I have to gitignore the copied files

11ty should support developers who wish to colocate their package's docs with their sources.

Maybe we can take inspiration from vite-plugin-pages's configuration for dirs:

export default {
  plugins: [
    Pages({
      dirs: [
        { dir: "src/pages", baseRoute: "" },
        { dir: "src/features/**/pages", baseRoute: "features" },
        { dir: "src/admin/pages", baseRoute: "admin" },
      ],
    }),
  ],
};

I wonder if a symlink would work here? I've seen a few people use them in the past; https://github.com/11ty/eleventy/search?q=symlink+is%3Aissue&type=issues

Or possibly using https://www.npmjs.com/package/symlink-dir if you don't want to set up symlinks manually.
Not sure how easy/useful git submodules would work. I feel like sometimes they're too awkward to keep updated.

it would be a burden on contributors to make them symlink files every time they clone the repo or add a package

There is an issue #2353 that talks about accepting an array for input. We can go to vote on that one.