-2

I would like to create a node.js file that has a script that will do the following:

  1. look in a certain directory for _*.html files, e.g. html files that start with an underscore.
  2. I guess loop through the directory for those files, choose the first one and copy the html inside the file.
  3. then have some kind of reference where the copied content will be inserted into the index.html file at the point where the name of the copied file is located. In other words, the contents of the _nav.html will be inserted into the index.html where there is a "@nav" line.
  4. Then continue iterating through the _*.html files, copy the contents and paste it into the index.html file at the designated location.

You can probably see where I am going with this. It basically compiles my partial html files into one index.html file.

I searched high and low and surprisingly couldn't find a script that would do this. Any help building such a script would be greatly appreciated.

disinfor
  • 10,865
  • 2
  • 33
  • 44
David
  • 55
  • 9
  • 1
    You mean https://stackoverflow.com/questions/16369649/include-html-blocks-using-node-js ? Why duplicate the code into files if you can include the files – mplungjan Dec 15 '22 at 20:13
  • Thanks for the info. It appears that the above example happens on the server side. I had the idea of it operating like sass. It takes the partial files like _navbar.scss, and compiles it into a css file in your public/distribution folder. I wanted to see if I could take partial html files like _navbar.html and have those compiled into the index.html file in the public/distribution folder. – David Dec 16 '22 at 19:09
  • Sure looks like you would be happier with any traditional _server-side rendering_ component that supports [_partials_](https://stackoverflow.com/questions/5404830/node-js-ejs-including-a-partial) such as EJS. – Wyck Dec 19 '22 at 19:39

1 Answers1

-1

Here is the solution. I'm sure it could use some refactoring but it suits my needs for now.

Note: The "replace-in-file" npm package needs to be installed but the "fs" package doesn't. From what I gather, this package is now part of Node.js by default. Correct me if i'm wrong.

const fs = require("fs");
const replace = require("replace-in-file");

// create dist directory
if (!fs.existsSync("dist")) {
  fs.mkdirSync("dist", (error) => {
    console.log("==> directory created");
    if (error) {
      console.log(error);
    }
  });
} else {
  console.log("==> Directory already exists");
}

// create the dist/index.file if not already there
if (!fs.existsSync("dist/index.html")) {
  fs.writeFileSync("dist/index.html", "blank file", (error) => {
    console.log("==> index.html created");
    if (error) {
      console.log(error);
    }
  });
} else {
  console.log("==> index.html already exists");
}

// copy the source index.html to the dist folder
fs.copyFile("src/index.html", "dist/index.html", (err) => {
  if (err) {
    console.log("Error Found:", err);
  }
  console.log("==> Index file contents copied");
});

// get list of files in src directory that start with "_"(underscore) which are the partial files
fs.readdir("./src/", (err, files) => {
  if (err) {
    console.log(err);
  } else {
    files.forEach((file) => {
      if (file.startsWith("_")) {

        // get the contents of the partial file and put it in a variable
        fs.readFile("./src/" + file, (err, data) => {
          if (err) throw err;
          textData = data.toString();

          // replace the placeholder text in the index.html file with the content from partial file
          const options = {
            files: "dist/index.html",
            from: file,
            to: textData,
          };

          try {
            const results = replace.sync(options);
            console.log("==> Replacement results:", results);
          } catch (error) {
            console.error("==> Error occurred:", error);
          }
        });
      }
    });
  }
});

This is my directory structure for the test. Its basic.

project-name/src/index.html
project-name/src/_navigation.html
project-name/src/_cards.html
project-name/src/_footer.html

The index.html looks like this.

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>PageTitle</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
  </head>

  <body>
    <div class="container">
      <h1 class="mt-5">Basic Template</h1>
      <p class="lead">Simple template to start your design with.</p>
    </div>

    _navigation.html

    _cards.html

    _footer.html

  </body>
</html>

I run it from the package.json with this script. I keep my node.js scripts in a utils folder in the root of the project.

"compile:html": "node utils/compile-html.js"

It basically creates the dist folder and an index.html file in that folder if not already there. Then it copies the contents of the src/index.html and pastes it into the dist/index.html. After that the script makes the changes to the dist/index.html and leaves the src/index.html alone. The script takes the contents of the partial files (e.g. _navigation.html) and replaces the file name text in the index.html (e.g. the _navigation.html line in the index.html file) with the content copied from the partial file.

David
  • 55
  • 9