sagold / handlebars-webpack-plugin

Renders your html-template at build time
161 stars 45 forks source link

Question about resource groups / folders #57

Open bneigher opened 4 years ago

bneigher commented 4 years ago

Awesome plugin. Have a pretty swift static site generator now!

I had a question about the proper way to make KNOWN resource group pages. For example:

data/
   schools.json
src/
    partials/
        nav.hbs
        footer.hbs
    index.hbs
    contact.hbs
    schools/
        school1.hbs
        school2.hbs

I have a fixed number of school pages, (in schools.json), and I want the page structure to model a rest resource group structure as illustrated above. I can't seem to understand how to properly accomplish this with the plugin.

For context, here is my webpack:

const path = require("path");
const HandlebarsPlugin = require("handlebars-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const postcssPresetEnv = require("postcss-preset-env");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const cssnano = require("cssnano");

const { makeDataReplacements, registerHandlersHelpers } = require("./webpack.helpers.js");

const mode = process.env.NODE_ENV || "production";
const PORT = process.env.PORT || 3000;

const sourceDir = path.join(__dirname, "src");
const templateDir = path.join(__dirname, "generated");
const buildDir = path.join(__dirname, "docs");

const isProd = mode === "production";
const prodPlugins = [new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i })];

module.exports = {
  mode,
  entry: path.join(sourceDir, "entry.js"),
  output: {
    path: buildDir,
    filename: isProd ? "bundle.[chunkhash].js" : "bundle.js",
    publicPath: ""
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.s?css$/,
        use: [
          MiniCssExtractPlugin.loader,
          { loader: "css-loader", options: { importLoaders: 1 } },
          isProd
            ? {
                loader: "postcss-loader",
                options: {
                  ident: "postcss",
                  plugins: () => [postcssPresetEnv(), cssnano()]
                }
              }
            : null,
          "sass-loader"
        ].filter(Boolean)
      },
      {
        test: /\.(eot|ttf|woff|woff2)$/,
        use: [
          {
            loader: "file-loader",
            options: { name: "fonts/[name].[ext]" }
          }
        ]
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        loaders: [
          {
            loader: "file-loader",
            options: {
              name: "img/[name].[hash:6].[ext]"
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(sourceDir, "views", "layout", "template.hbs"),
      filename: path.join(templateDir, "template.hbs"),
      inject: false
    }),
    new HandlebarsPlugin({
      htmlWebpackPlugin: {
        enabled: true,
        prefix: "html"
      },
      entry: path.join(sourceDir, "views", "*.hbs"),
      output: name => {
        const page = name !== "index" ? name : "";
        return path.join(buildDir, page, "index.html");
      },
      data: path.join(sourceDir, "data", "*.json"),
      partials: [
        path.join(templateDir, "template.hbs"),
        path.join(sourceDir, "views", "partials", "*.hbs")
      ],
      onBeforeSetup: Handlebars => {
        return registerHandlersHelpers(Handlebars);
      },
      onBeforeRender: (Handlebars, data) => {
        return makeDataReplacements(data);
      }
    }),
    new CopyWebpackPlugin([
      {
        from: path.join(sourceDir, "img"),
        to: "img"
      },
      {
        from: "CNAME.txt",
        to: "CNAME",
        toType: "file"
      }
    ]),
    new MiniCssExtractPlugin({
      filename: isProd ? "[name].[chunkhash].css" : "[name].css",
      chunkFilename: "[id].css",
      fallback: "style-loader",
      use: [{ loader: "css-loader", options: { minimize: isProd } }]
    })
  ].concat(isProd ? prodPlugins : []),
  devServer: {
    contentBase: buildDir,
    compress: true,
    port: PORT,
    watchOptions: {
      poll: true
    }
  }
};

None of the folders or .hbs inside the folders are beings built correctly.. and when trying to insert a wildcard directory for partials on entry, it makes everything flat

sagold commented 4 years ago

Hi bneigher.

Do i understand it correctly, that you want to maintain the directory structure of your partials for the output results of the html?