eta icon indicating copy to clipboard operation
eta copied to clipboard

[3.X - Express] Support res.render()

Open enzoclock opened this issue 1 year ago • 2 comments

Hello 👋 Before anything, thank you for this nice template engine :)

Context

Unless I misread the documentation, it seems that V3 doesn't support the good'old Express res.render() anymore.

During setup, it is not possible to app.engine("eta", eta.render) to define eta as an express view engine.

My poor solution

Here is my walk around
const express = require("express");
const { Eta } = require("eta");

// Create app
const app = express();

// Setup eta
const eta = new Eta({ views: "./views" });
app.engine("eta", buildEtaEngine());
app.set("view engine", "eta");

// Home route
app.get("/", (req, res) => {
  res.render("home", { message: "Hello John" });
});

// Start server
app.listen(3000, () => {
  console.log(`Listening at http://localhost:${3000}`);
});


function buildEtaEngine() {
  return (path, opts, callback) => {
    try {
      const fileContent = eta.readFile(path);
      const rendered = eta.renderString(fileContent, opts);
      callback(null, rendered);
    } catch (error) {
      callback(error);
    };
  };
}

Question

Any reason for it not being supported anymore ?

Would it be interesting to add a eta.getExpressEngine() method or equivalent so the required setup to use the res.render() syntax with Express remains simple ?

Note

I'm not so familiar with open source contributions, let me know if anything is unclear

enzoclock avatar Mar 19 '24 16:03 enzoclock

@enzoclock thank you! I appreciate this suggestion, but I think it's best to keep the Eta API as minimal as possible.

However, I do like your solution. Maybe you could submit a PR to add that to the Eta documentation here?

bgub avatar Mar 20 '24 00:03 bgub

var w = express()
var eta = new Eta({ views: path.join(__dirname, "views"), cache: false })
w.engine("eta", buildEtaEngine())
w.set("view engine", "eta")
w.set("views",eta.config.views) // idk why need add this, even though the config is already there above
function buildEtaEngine(): (
	path: string,
	opts: any,
	callback: (error: Error | null, renderedTemplate?: string) => void
) => void {
	return (path: string, opts: any, callback: (error: Error | null, renderedTemplate?: string) => void) => {
		try {
			const fileContent = eta.readFile(path)
			const renderedTemplate = eta.renderString(fileContent, opts)
			callback(null, renderedTemplate)
		} catch (error) {
			callback(error as Error)
		}
	}
}

for some reason the path doesn't work if I don't add w.set("views",eta.config.views) or maybe views: path.join(__dirname, "views") is never read?

akbaryahya avatar Apr 18 '24 14:04 akbaryahya