diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 9e3a490..0000000 --- a/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root = true - -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true -end_of_line = lf -indent_size = 2 -indent_style = space diff --git a/.eslintrc.js b/.eslintrc.js index 011bae7..a146780 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,10 +1,10 @@ module.exports = { - extends: 'airbnb-base', - parserOptions: { - sourceType: 'script', - }, - env: { - browser: true, - node: true, - }, -}; + extends: "airbnb-base", + parserOptions: { + sourceType: "script", + }, + env: { + browser: true, + node: true, + }, +} diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 0d5e4cb..1f633f1 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -1,34 +1,34 @@ name: Express Edge CI on: - push: - branches: - - master - - 'feature/*' - - 'hotfix/*' - pull_request: - branches: [ main ] + push: + branches: + - master + - "feature/*" + - "hotfix/*" + pull_request: + branches: [main] jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - node-version: ['18', '16', '14'] + build: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: ["18", "16"] - steps: - - name: Checkout code - uses: actions/checkout@v2 + steps: + - name: Checkout code + uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - - - name: Install Dependencies - run: npm install + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} - - name: Run Linter and Tests - run: | - npm test - npm run eslint + - name: Install Dependencies + run: npm install + + - name: Run Linter and Tests + run: | + npm test + npm run eslint diff --git a/.gitignore b/.gitignore index fbadd14..5dbed20 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .idea -/node_modules -yarn.lock .vscode +/node_modules/ +/dist/ package-lock.json +yarn.lock +pnpm-lock.yaml diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..178135c --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +/dist/ diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..511189b --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,5 @@ +module.exports = { + semi: false, + tabWidth: 4, + arrowParens: "avoid", +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2840e6b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG + +## v3.0.0+ + +- Dropped Node v14 support. diff --git a/LICENSE.md b/LICENSE similarity index 94% rename from LICENSE.md rename to LICENSE index b302eb8..efc5c87 100644 --- a/LICENSE.md +++ b/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) +MIT License -Copyright (c) Daniel Eckermann +Copyright (c) 2018 Daniel Eckermann Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index 2608203..4889a8b 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,51 @@ -# express-edge +# Edge Templating Engine for Express -> Use Edge templating engine with Express - -[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fecrmnn%2Fexpress-edge%2Fbadge%3Fref%3Dmaster&style=flat-square&label=build)](https://github.com/ecrmnn/express-edge/actions) -[![npm version](https://img.shields.io/badge/Node.js-v14%2B-green?style=flat-square)](https://github.com/ecrmnn/express-edge) -[![npm version](https://img.shields.io/npm/v/express-edge.svg?style=flat-square)](http://badge.fury.io/js/express-edge) -[![npm downloads](https://img.shields.io/npm/dm/express-edge.svg?style=flat-square)](http://badge.fury.io/js/express-edge) -[![npm license](https://img.shields.io/npm/l/express-edge.svg?style=flat-square)](http://badge.fury.io/js/express-edge) -[![prs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) -[![eslint](https://img.shields.io/badge/code_style-airbnb-blue.svg?style=flat-square)](https://github.com/airbnb/javascript) +Express Edge is an effortless solution for integrating the [Edge](https://github.com/edge-js/edge) templating engine with [Express](https://github.com/expressjs/express). Simplify your templating process and enjoy seamless compatibility. ## Installation ```bash -npm install express-edge --save +npm i express-edge ``` ## Usage See the [Edge documentation](https://docs.adonisjs.com/guides/views/introduction) for how to structure your templates. -Requires Node.js 14+ from `express-edge@3` +You'll need at least [Node](https://github.com/nodejs/node) v15 or higher to use Express Edge v3. + +```js +const express = require("express") +const engine = require("express-edge") -```javascript -const express = require('express'); -const app = express(); -const engine = require('express-edge'); +const app = express() // Automatically sets view engine and adds dot notation to app.render -app.use(engine); -app.set('views', `${__dirname}/views`); +app.use(engine) +app.set("views", `${__dirname}/views`) -// Configure view caching -app.enable('view cache'); -// --- or --- -app.diable('view cache'); +app.get("/", (req, res) => { + res.render("index", { greeting: "Hello world" }) +}) + +app.listen(PORT, () => { + console.log(`Listening on http://localhost:${PORT}`) +}) +``` + +`views/index.edge`: + +```html +

{{ greeting }}

+``` -app.get('/', (req, res) => { - res.render('users.index', { users }); -}); +### Configure view caching -app.listen(3000); +```js +app.enable("view cache") +// app.disable('view cache'); ``` -## License +## Development -MIT © [Daniel Eckermann](http://danieleckermann.com) +Run `npm transpile` to build the `./dist` folder. diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 33f50fb..0000000 --- a/dist/index.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict'; - -var fs = require('fs'); - -var _require = require('edge.js'), - Edge = _require.Edge; - -var engine = function engine(req, res, next) { - /* - |------------------------------------------------------------------------------------------------- - | Override the app.render function so that we can use dot notation - |------------------------------------------------------------------------------------------------- - */ - - var render = res.render; - - - res.render = function _render(view, options, callback) { - var self = this; - - render.call(self, view.replace(/\./gi, '/'), options, callback); - }; - - /* - |------------------------------------------------------------------------------------------------- - | Register the edge view engine - |------------------------------------------------------------------------------------------------- - */ - - req.app.engine('edge', function (filePath, options, callback) { - var cache = req.app.settings['view cache'] || false; - req.app.settings['view cache'] = cache; - - var edge = new Edge({ cache: cache }); - edge.mount('default', req.app.settings.views); - var template = edge.getRenderer(); - - fs.readFile(filePath, 'utf-8', function (err, content) { - if (err) { - return callback(err); - } - - return callback(null, template.renderRawSync(content, options)); - }); - }); - - /* - |------------------------------------------------------------------------------------------------- - | Set the app view engine - |------------------------------------------------------------------------------------------------- - */ - - req.app.set('view engine', 'edge'); - - next(); -}; - -module.exports = engine; \ No newline at end of file diff --git a/package.json b/package.json index 9d71612..c83b755 100644 --- a/package.json +++ b/package.json @@ -1,56 +1,63 @@ { - "name": "express-edge", - "version": "3.0.0", - "description": "Use Edge templating engine with Express", - "main": "dist/index.js", - "scripts": { - "pretest": "rm -rf dist && npm run transpile", - "test": "node_modules/.bin/mocha test/tests.js", - "transpile": "node_modules/babel-cli/bin/babel.js src --out-dir dist", - "eslint": "node_modules/.bin/eslint src/ test/", - "prepublishOnly": "npm run transpile" - }, - "repository": { - "type": "git", - "url": "https://github.com/ecrmnn/express-edge" - }, - "babel": { - "presets": [ - "env" + "name": "express-edge", + "version": "3.0.0", + "description": "Use Edge templating engine with Express", + "license": "MIT", + "main": "dist/index.js", + "scripts": { + "pretest": "rm -rf dist && npm run transpile", + "test": "mocha test/tests.js", + "transpile": "babel src --out-dir dist", + "eslint": "eslint src/ test/", + "prepublishOnly": "npm run transpile", + "lint": "prettier --check .", + "format": "prettier --write ." + }, + "dependencies": { + "edge.js": "^5.5.1" + }, + "devDependencies": { + "babel-cli": "^6.26.0", + "babel-core": "^6.26.3", + "babel-preset-env": "^1.7.0", + "body-parser": "^1.20.2", + "chai": "^4.3.7", + "eslint": "^8.38.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.27.5", + "express": "^4.18.2", + "mocha": "^10.2.0", + "prettier": "^3.0.1", + "supertest": "^6.3.3" + }, + "engines": { + "node": ">=15" + }, + "repository": { + "type": "git", + "url": "https://github.com/ecrmnn/express-edge" + }, + "babel": { + "presets": [ + "env" + ] + }, + "author": { + "name": "Daniel Eckermann", + "email": "danieleckermann@gmail.com", + "url": "http://danieleckermann.com" + }, + "bugs": { + "url": "https://github.com/ecrmnn/express-edge/issues" + }, + "homepage": "https://github.com/ecrmnn/express-edge", + "keywords": [ + "express", + "express.js", + "adonis", + "edge", + "template", + "templating", + "engine" ] - }, - "keywords": [ - "express", - "express.js", - "adonis", - "edge", - "template", - "templating" - ], - "author": { - "name": "Daniel Eckermann", - "email": "danieleckermann@gmail.com", - "url": "http://danieleckermann.com" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/ecrmnn/express-edge/issues" - }, - "homepage": "https://github.com/ecrmnn/express-edge", - "devDependencies": { - "babel-cli": "^6.26.0", - "babel-core": "^6.26.3", - "babel-preset-env": "^1.7.0", - "body-parser": "^1.20.2", - "chai": "^4.3.7", - "eslint": "^8.38.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-plugin-import": "^2.27.5", - "express": "^4.18.2", - "mocha": "^10.2.0", - "supertest": "^6.3.3" - }, - "dependencies": { - "edge.js": "^5.5.1" - } } diff --git a/src/index.js b/src/index.js index 2519d54..038f8bd 100644 --- a/src/index.js +++ b/src/index.js @@ -1,53 +1,53 @@ -const fs = require('fs'); -const { Edge } = require('edge.js'); +const fs = require("fs") +const { Edge } = require("edge.js") const engine = (req, res, next) => { - /* - |------------------------------------------------------------------------------------------------- - | Override the app.render function so that we can use dot notation - |------------------------------------------------------------------------------------------------- - */ + /* + |------------------------------------------------------------------------------------------------- + | Override the app.render function so that we can use dot notation + |------------------------------------------------------------------------------------------------- + */ - const { render } = res; + const { render } = res - res.render = function _render(view, options, callback) { - const self = this; + res.render = function _render(view, options, callback) { + const self = this - render.call(self, view.replace(/\./gi, '/'), options, callback); - }; + render.call(self, view.replaceAll(".", "/"), options, callback) + } - /* - |------------------------------------------------------------------------------------------------- - | Register the edge view engine - |------------------------------------------------------------------------------------------------- - */ + /* + |------------------------------------------------------------------------------------------------- + | Register the edge view engine + |------------------------------------------------------------------------------------------------- + */ - req.app.engine('edge', (filePath, options, callback) => { - const cache = req.app.settings['view cache'] || false; - req.app.settings['view cache'] = cache; + req.app.engine("edge", (filePath, options, callback) => { + const cache = req.app.settings["view cache"] || false + req.app.settings["view cache"] = cache - const edge = new Edge({ cache }); - edge.mount('default', req.app.settings.views); - const template = edge.getRenderer(); + const edge = new Edge({ cache }) + edge.mount("default", req.app.settings.views) + const template = edge.getRenderer() - fs.readFile(filePath, 'utf-8', (err, content) => { - if (err) { - return callback(err); - } + fs.readFile(filePath, "utf-8", (err, content) => { + if (err) { + return callback(err) + } - return callback(null, template.renderRawSync(content, options)); - }); - }); + return callback(null, template.renderRawSync(content, options)) + }) + }) - /* - |------------------------------------------------------------------------------------------------- - | Set the app view engine - |------------------------------------------------------------------------------------------------- - */ + /* + |------------------------------------------------------------------------------------------------- + | Set the app view engine + |------------------------------------------------------------------------------------------------- + */ - req.app.set('view engine', 'edge'); + req.app.set("view engine", "edge") - next(); -}; + next() +} -module.exports = engine; +module.exports = engine diff --git a/test/mocha.opts b/test/mocha.opts index 37b2359..2587a8c 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1 +1 @@ ---timeout=5000 \ No newline at end of file +--timeout=5000 diff --git a/test/tests.js b/test/tests.js index 3f6c2c9..8588296 100644 --- a/test/tests.js +++ b/test/tests.js @@ -1,130 +1,137 @@ -const express = require('express'); -const bodyParser = require('body-parser'); - -const { describe, it, before } = require('mocha'); -const { expect } = require('chai'); -const request = require('supertest'); -const dist = require('../dist'); - -let app; - -describe('View Test Suite', () => { - before(() => { - app = express(); - - app.use(bodyParser.json()); - app.use(dist); - - app.set('views', `${__dirname}/views`); - - app.get('/hello', (req, res) => res.render('sub.hello', { name: 'John Doe' })); - app.get('/nested', (req, res) => res.render('sub.nested.hello')); - app.get('/conditionals', (req, res) => res.render('conditionals', req.body)); - app.post('/conditionals', (req, res) => res.render('conditionals', req.body)); - app.post('/iteration', (req, res) => res.render('iteration', req.body)); - app.post('/partial', (req, res) => res.render('partial', req.body)); - app.post('/cache', (req, res) => res.render('cache', req.body)); - }); - - it('should be able to render a basic view', (done) => { - request(app) - .get('/hello') - .end((err, res) => { - expect(res.text.trim()).to.eql('Hello world, John Doe'); - done(); - }); - }); - - it('should be able to render a nested basic view', (done) => { - request(app) - .get('/nested') - .end((err, res) => { - expect(res.text.trim()).to.eql('hello world'); - done(); - }); - }); - - it('should be able to render conditionals', (done) => { - request(app) - .post('/conditionals') - .send({ name: 'daniel' }) - .end((err, res) => { - expect(res.text.trim()).to.eql('hello, daniel'); - done(); - }); - }); - - it('should be able to render conditionals without data', (done) => { - request(app) - .get('/conditionals') - .end((err, res) => { - expect(res.text.trim()).to.eql('hello'); - done(); - }); - }); - - it('should be able to iterate data', (done) => { - request(app) - .post('/iteration') - .send({ - users: [{ - name: 'Daniel Eckermann', - username: 'ecrmnn', - }], - }) - .end((err, res) => { - expect(res.text.trim()).to.eql('Daniel Eckermann (ecrmnn)'); - done(); - }); - }); - - it('should be able to user partials', (done) => { - request(app) - .post('/partial') - .send({ - users: [{ - name: 'Daniel Eckermann', - username: 'ecrmnn', - }], - }) - .end((err, res) => { - expect(res.text.trim()).to.eql('Daniel Eckermann (ecrmnn)'); - done(); - }); - }); -}); - -describe('Cache Test Suite', () => { - before(() => { - app = express(); - - app.use(bodyParser.json()); - app.use(dist); - - app.set('views', `${__dirname}/views`); - - app.get('/hello', (req, res) => res.render('cache')); - }); - - it('should detect that view cache is enabled', (done) => { - app.enable('view cache'); - - request(app) - .get('/hello') - .end((err, res) => { - expect(res.text.trim()).to.eql('Cache enabled: true'); - done(); - }); - }); - - it('should detect that view cache is diabled', (done) => { - app.disable('view cache'); - - request(app) - .get('/hello') - .end((err, res) => { - expect(res.text.trim()).to.eql('Cache enabled: false'); - done(); - }); - }); -}); +const express = require("express") +const bodyParser = require("body-parser") +const { describe, it, before } = require("mocha") +const { expect } = require("chai") +const request = require("supertest") +const engine = require("../dist/index.js") + +let app + +describe("View Test Suite", () => { + before(() => { + app = express() + app.use(bodyParser.json()) + app.use(engine) + app.set("views", `${__dirname}/views`) + + app.get("/hello", (_, res) => + res.render("sub/hello", { name: "John Doe" }), + ) + app.get("/nested", (_, res) => res.render("sub/nested/hello")) + app.get("/conditionals", (req, res) => + res.render("conditionals", req.body), + ) + app.post("/conditionals", (req, res) => + res.render("conditionals", req.body), + ) + app.post("/iteration", (req, res) => res.render("iteration", req.body)) + app.post("/partial", (req, res) => res.render("partial", req.body)) + app.post("/cache", (req, res) => res.render("cache", req.body)) + }) + + it("should be able to render a basic view", done => { + request(app) + .get("/hello") + .end((_, res) => { + expect(res.text.trim()).to.eql("Hello John Doe") + done() + }) + }) + + it("should be able to render a nested basic view", done => { + request(app) + .get("/nested") + .end((_, res) => { + expect(res.text.trim()).to.eql("Hello World") + done() + }) + }) + + it("should be able to render conditionals", done => { + request(app) + .post("/conditionals") + .send({ name: "Daniel" }) + .end((_, res) => { + expect(res.text.trim()).to.eql("Hello Daniel") + done() + }) + }) + + it("should be able to render conditionals without data", done => { + request(app) + .get("/conditionals") + .end((_, res) => { + expect(res.text.trim()).to.eql("Hello") + done() + }) + }) + + it("should be able to iterate data", done => { + request(app) + .post("/iteration") + .send({ + users: [ + { + name: "Daniel Eckermann", + username: "ecrmnn", + }, + ], + }) + .end((_, res) => { + expect(res.text.trim()).to.eql("Daniel Eckermann (ecrmnn)") + done() + }) + }) + + it("should be able to user partials", done => { + request(app) + .post("/partial") + .send({ + users: [ + { + name: "Daniel Eckermann", + username: "ecrmnn", + }, + ], + }) + .end((_, res) => { + expect(res.text.trim()).to.eql("Daniel Eckermann (ecrmnn)") + done() + }) + }) +}) + +describe("Cache Test Suite", () => { + before(() => { + app = express() + + app.use(bodyParser.json()) + app.use(engine) + + app.set("views", `${__dirname}/views`) + + app.get("/hello", (_, res) => res.render("cache")) + }) + + it("should detect that view cache is enabled", done => { + app.enable("view cache") + + request(app) + .get("/hello") + .end((_, res) => { + expect(res.text.trim()).to.eql("Cache enabled: true") + done() + }) + }) + + it("should detect that view cache is diabled", done => { + app.disable("view cache") + + request(app) + .get("/hello") + .end((_, res) => { + expect(res.text.trim()).to.eql("Cache enabled: false") + done() + }) + }) +}) diff --git a/test/views/conditionals.edge b/test/views/conditionals.edge index b356a48..82aec62 100644 --- a/test/views/conditionals.edge +++ b/test/views/conditionals.edge @@ -1,5 +1,5 @@ @if(name) - hello, {{ name }} + Hello {{ name }} @else - hello + Hello @endif diff --git a/test/views/iteration.edge b/test/views/iteration.edge index f2fef9d..91b6a3b 100644 --- a/test/views/iteration.edge +++ b/test/views/iteration.edge @@ -1,3 +1,3 @@ @each(user in users) -{{ user.name }} ({{ user.username }}) + {{ user.name }} ({{ user.username }}) @endeach diff --git a/test/views/partials/iteration_partial.edge b/test/views/partials/iteration_partial.edge index f2fef9d..91b6a3b 100644 --- a/test/views/partials/iteration_partial.edge +++ b/test/views/partials/iteration_partial.edge @@ -1,3 +1,3 @@ @each(user in users) -{{ user.name }} ({{ user.username }}) + {{ user.name }} ({{ user.username }}) @endeach diff --git a/test/views/sub/hello.edge b/test/views/sub/hello.edge index fc0d397..cd775cb 100644 --- a/test/views/sub/hello.edge +++ b/test/views/sub/hello.edge @@ -1 +1 @@ -Hello world, {{ name }} +Hello {{ name }} diff --git a/test/views/sub/nested/hello.edge b/test/views/sub/nested/hello.edge index 3b18e51..557db03 100644 --- a/test/views/sub/nested/hello.edge +++ b/test/views/sub/nested/hello.edge @@ -1 +1 @@ -hello world +Hello World