├── .eleventy.js
├── .github
└── workflows
│ └── cla.yml
├── .gitignore
├── elements.mjs
├── elements
├── my-footer.mjs
└── my-header.mjs
├── index.html
├── index.json
├── package.json
├── plugin.js
├── readme.md
├── rollup.config.js
├── utils.js
└── vendor
├── enhance-ssr.js
└── readme.md
/.eleventy.js:
--------------------------------------------------------------------------------
1 | let plugin = require('./plugin.js')
2 |
3 | module.exports = function (eleventyConfig) {
4 | let extension = 'html'
5 | eleventyConfig.addTemplateFormats(extension)
6 | eleventyConfig.addExtension(extension, plugin)
7 | eleventyConfig.addWatchTarget("./elements/**/*.mjs")
8 | }
9 |
--------------------------------------------------------------------------------
/.github/workflows/cla.yml:
--------------------------------------------------------------------------------
1 | name: "CLA Assistant"
2 | on:
3 | issue_comment:
4 | types: [created]
5 | pull_request_target:
6 | types: [opened,closed,synchronize]
7 |
8 | permissions:
9 | actions: write
10 | contents: write
11 | pull-requests: write
12 | statuses: write
13 |
14 | jobs:
15 | CLAAssistant:
16 | runs-on: ubuntu-latest
17 | steps:
18 | - name: "CLA Assistant"
19 | if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
20 | uses: contributor-assistant/github-action@v2.4.0
21 | env:
22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 | PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
24 | with:
25 | path-to-signatures: 'signatures/v1/cla.json'
26 | path-to-document: 'https://github.com/enhance-dev/.github/blob/main/CLA.md'
27 | branch: 'main'
28 | allowlist: brianleroux,colepeters,kristoferjoseph,macdonst,ryanbethel,ryanblock,tbeseda
29 | remote-organization-name: enhance-dev
30 | remote-repository-name: .github
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | _site
3 |
--------------------------------------------------------------------------------
/elements.mjs:
--------------------------------------------------------------------------------
1 | import { importWithoutCache } from './utils.js'
2 |
3 | const header = await importWithoutCache('./elements/my-header.mjs')
4 | const footer = await importWithoutCache('./elements/my-footer.mjs')
5 |
6 | export default {
7 | 'my-header': header.default,
8 | 'my-footer': footer.default
9 | }
10 |
--------------------------------------------------------------------------------
/elements/my-footer.mjs:
--------------------------------------------------------------------------------
1 | export default function Footer ({ html, state }) {
2 | return html``
3 | }
4 |
--------------------------------------------------------------------------------
/elements/my-header.mjs:
--------------------------------------------------------------------------------
1 | export default function Header ({ html }) {
2 | return html``
3 | }
4 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 | hi from cloud eh
3 |
4 |
--------------------------------------------------------------------------------
/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "initialState": {
3 | "whatever": true,
4 | "you": 1,
5 | "want": "yay"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@enhance/eleventy-plugin",
3 | "version": "1.0.2",
4 | "main": "plugin.js",
5 | "scripts": {
6 | "build": "rollup -c",
7 | "start": "eleventy --serve"
8 | },
9 | "devDependencies": {
10 | "@11ty/eleventy": "^1.0.1",
11 | "@enhance/ssr": "^3.0.0",
12 | "@rollup/plugin-commonjs": "^22.0.1",
13 | "@rollup/plugin-json": "^4.1.0",
14 | "@rollup/plugin-node-resolve": "^13.3.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/plugin.js:
--------------------------------------------------------------------------------
1 | let enhance = require('./vendor/enhance-ssr.js')
2 | let { join } = require('path')
3 | let { existsSync: exists, readdirSync: ls } = require('fs')
4 | let { importWithoutCache } = require('./utils')
5 |
6 | module.exports = {
7 | async compile (inputContent) {
8 | return async function compiler ({ initialState={} }) {
9 | let elements = await read()
10 | let html = enhance({ elements, initialState })
11 | return html`${ inputContent }`
12 | }
13 | }
14 | }
15 |
16 | async function read () {
17 |
18 | let pathToModule = join(process.cwd(), 'elements.mjs')
19 | let pathToDirectory = join(process.cwd(), 'elements')
20 |
21 | if (exists(pathToModule)) {
22 | // read explicit elements manifest
23 | let els = await importWithoutCache(pathToModule)
24 | return els.default || els
25 | }
26 | else if (exists(pathToDirectory)) {
27 | // generate based on elements/ directory
28 | let els = {}
29 | let raw = ls(pathToDirectory)
30 | for (let e of raw) {
31 | let tag = e.replace('.mjs', '')
32 | let mod = await importWithoutCache(join(pathToDirectory, e))
33 | els[tag] = mod.default
34 | }
35 | return els
36 | }
37 | else {
38 | // generate based on page.html or page.mjs requested
39 | throw Error('cannot find `elements.mjs` or an `elements/` folder')
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # `@enhance/eleventy-plugin`
2 |
3 | Build static websites with custom elements.
4 |
5 | ## Quickstart
6 |
7 | Create a project.
8 |
9 | ``` bash
10 | mkdir -p myproject && cd myproject
11 | npm init -y
12 | npm install @11ty/eleventy @enhance/eleventy-plugin
13 | ```
14 |
15 | Add some handy shortcuts to `scripts` in `package.json`.
16 |
17 | ```json
18 | {
19 | "scripts": {
20 | "start": "npx @11ty/eleventy --serve"
21 | }
22 | }
23 | ```
24 |
25 | Add the `@enhance/plugin-eleventy` to `.eleventy.js` config file.
26 |
27 | ```javascript
28 | let plugin = require('@enhance/eleventy-plugin')
29 |
30 | module.exports = function (eleventyConfig) {
31 | let extension = 'html'
32 | eleventyConfig.addTemplateFormats(extension)
33 | eleventyConfig.addExtension(extension, plugin)
34 | eleventyConfig.addWatchTarget("./elements/**/*.mjs")
35 | }
36 | ```
37 |
38 | Write some HTML.
39 |
40 | ```html
41 |
42 |
43 | powerful html here
44 |
45 | ```
46 |
47 | Define custom element templates in a folder named `elements`.
48 |
49 | ```javascript
50 | /** elements/my-header.mjs */
51 | export default function header ({ html }) {
52 | return html``
53 | }
54 | ```
55 |
56 | ```javascript
57 | /** elements/my-footer.mjs */
58 | export default function footer ({ html, state }) {
59 | return html`
60 |
64 | `
65 | }
66 | ```
67 |
68 | Run `npm start`, and preview at `http://localhost:8080`.
69 |
70 | ## Add data
71 |
72 | Add `index.json` with some default data, and preview result in the footer.
73 |
74 | ```json
75 | {
76 | "initialState": { "custom": "data", "is": "here" }
77 | }
78 | ```
79 |
80 | ## Rename elements
81 |
82 | If you want to configure your own element tag names create `./elements.mjs` to explicitly define tags:
83 |
84 | ```javascript
85 | import header from './elements/my-header.mjs'
86 | import footer from './elements/my-footer.mjs'
87 |
88 | export default {
89 | 'my-header': header,
90 | 'my-footer': footer
91 | }
92 | ```
93 |
94 | > Don't forget to update your corresponding `index.html`!
95 |
96 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import commonjs from '@rollup/plugin-commonjs'
2 | import json from '@rollup/plugin-json'
3 | import { nodeResolve } from '@rollup/plugin-node-resolve';
4 |
5 | export default {
6 | input: 'node_modules/@enhance/ssr/index.mjs',
7 | output: {
8 | file: `vendor/enhance-ssr.js`,
9 | format: 'cjs'
10 | },
11 | plugins: [
12 | nodeResolve(),
13 | commonjs({ignore: ['fs', 'path']}),
14 | json()
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/utils.js:
--------------------------------------------------------------------------------
1 | const importWithoutCache = async (path) => {
2 | return await import(`${path}?cacheBust=${Date.now()}`)
3 | }
4 |
5 | exports.importWithoutCache = importWithoutCache;
--------------------------------------------------------------------------------
/vendor/readme.md:
--------------------------------------------------------------------------------
1 | we have to do this because enhance-ssr is a node-native esmodule (which can't be loaded by a node-native commonjs module because reasons)
2 |
--------------------------------------------------------------------------------