Skip to content

Commit d2dbb06

Browse files
committed
allow inPlace template compilation using ejs
1 parent 6d7a34d commit d2dbb06

File tree

19 files changed

+14645
-29
lines changed

19 files changed

+14645
-29
lines changed

.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["env"]
3+
}

build/index.js

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ const collections = require('metalsmith-collections');
88
const permalinks = require('metalsmith-permalinks');
99
const linkcheck = require('metalsmith-linkcheck');
1010
const dates = require('metalsmith-jekyll-dates');
11-
const inPlace = require('metalsmith-in-place');
12-
const layouts = require('metalsmith-layouts');
11+
const assets = require('metalsmith-assets');
1312
const watch = require('metalsmith-watch');
1413
const when = require('metalsmith-if');
1514

1615
// custom plugins
1716
const changeExt = require('./plugins/change-ext');
1817
const markdown = require('./plugins/markdown');
18+
const partials = require('./plugins/partials');
19+
const layouts = require('./plugins/layouts');
1920
const toc = require('./plugins/toc');
2021

2122
const isDev = process.argv[2] === '--dev';
@@ -80,24 +81,24 @@ Metalsmith(cwd)
8081
}
8182
]
8283
}))
83-
// allow inPlace to process files
84-
.use(changeExt({
85-
pattern: `*.html`,
86-
ext: '.ejs'
87-
}))
88-
// wrap content in handlebars layouts
84+
// render all files in side a layout if specified
8985
.use(layouts({
90-
engine: 'ejs',
9186
default: 'default.ejs',
92-
partials: 'layouts/_partials',
93-
partialExtension: '.ejs',
94-
rename: false
87+
pattern: '**/*',
9588
}))
96-
// allow using template features inside the content directory
97-
.use(inPlace({
98-
engineOptions: {
99-
partials: 'layouts/_partials',
100-
}
89+
// re-run the render for newly inserted template features
90+
.use(layouts({
91+
inPlace: true,
92+
pattern: '**/*'
93+
}))
94+
// rename remaining .ejs files to html
95+
.use(changeExt({
96+
pattern: `**/*.ejs`,
97+
ext: '.html'
98+
}))
99+
// include our static assets
100+
.use(assets({
101+
source: './static'
101102
}))
102103
// finally check if we have broken links
103104
.use(linkcheck({
@@ -106,6 +107,6 @@ Metalsmith(cwd)
106107
// build the site
107108
.build((err) => {
108109
if (err) {
109-
console.log(err.toString())
110+
throw err;
110111
}
111112
});

build/plugins/change-ext.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ function plugin(opts) {
77
Object.keys(files).forEach((file) => {
88
if (multimatch(file, opts.pattern).length) {
99
const data = files[file];
10-
const new_name = path.extname(file) + opts.ext;
10+
const new_name = file.replace(path.extname(file), opts.ext);
11+
1112
delete files[file];
1213
files[new_name] = data;
1314
}

build/plugins/layouts.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const multimatch = require('multimatch');
2+
const fs = require('fs');
3+
const ejs = require('ejs');
4+
5+
function plugin(opts) {
6+
const options = Object.assign({
7+
directory: 'layouts',
8+
default: 'layout.ejs',
9+
inPlace: false,
10+
pattern: '*.ejs',
11+
options: {
12+
views: ['layouts']
13+
}
14+
}, opts);
15+
16+
return function (files, metalsmith, done) {
17+
Object.keys(files).forEach((file) => {
18+
if (!multimatch(file, options.pattern).length) {
19+
return;
20+
}
21+
22+
const data = files[file];
23+
data.contents = data.contents.toString();
24+
const context = Object.assign({}, metalsmith.metadata(), data);
25+
26+
let rendered;
27+
if (options.inPlace) {
28+
rendered = ejs.render(data.contents, context, options.options);
29+
} else {
30+
const template = metalsmith.path(
31+
options.directory,
32+
data.layout || options.default
33+
);
34+
const str = fs.readFileSync(template).toString();
35+
rendered = ejs.render(str, context, options.options);
36+
}
37+
38+
data.contents = rendered;
39+
});
40+
41+
done();
42+
}
43+
}
44+
45+
module.exports = plugin;

build/plugins/partials.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const multimatch = require('multimatch');
2+
const path = require('path');
3+
const fs = require('fs');
4+
5+
function plugin(opts) {
6+
const options = Object.assign({
7+
path: 'partials',
8+
base: '',
9+
pattern: '*.*'
10+
}, opts);
11+
12+
return function (files, metalsmith, done) {
13+
const metadata = metalsmith.metadata();
14+
metadata.partials = metadata.partials || {};
15+
16+
let partials = fs.readdirSync(metalsmith.path(options.path));
17+
partials = partials.filter(file => multimatch(file, options.pattern).length);
18+
partials = partials.map(file => file.replace(path.extname(file), ''));
19+
20+
partials.forEach((partial) => {
21+
metadata.partials[partial] = (options.base ? options.base + path.sep : '') + partial;
22+
});
23+
24+
Object.keys(files).forEach((file) => {
25+
const relativePartials = {};
26+
const rootPath = path.relative(file, metalsmith.path());
27+
partials.forEach((partial) => {
28+
relativePartials[partial] = `${rootPath}${path.sep}${options.path}${path.sep}${partial}`;
29+
});
30+
files[file].partials = relativePartials;
31+
});
32+
33+
done();
34+
}
35+
}
36+
37+
module.exports = plugin;

build/plugins/toc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ function plugin(opts) {
2626
}
2727
} else {
2828
data.toc = false;
29+
data.layout = data.layout || 'no_sidebar.ejs'
2930
}
3031
});
3132
done();

content/index_en.ejs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,22 @@
1-
Index
1+
---
2+
layout: landing.ejs
3+
---
4+
5+
<div class="bg-blue-dark">
6+
<div class="container mx-auto p-8">
7+
Index
8+
</div>
9+
</div>
10+
11+
<div class="container mx-auto p-8">
12+
<div class="flex -mx-8">
13+
<div class="w-1/2 px-8 bg-grey-light">
14+
<h4>Docs</h4>
15+
<%- include('_partials/links', { posts: collections.blog }) %>
16+
</div>
17+
<div class="w-1/2 px-8 bg-grey-light">
18+
<h4>Posts</h4>
19+
<%- include('_partials/links', { posts: collections.docs }) %>
20+
</div>
21+
</div>
22+
</div>

content/index_hu.ejs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1+
---
2+
layout: landing.ejs
3+
---
4+
15
HU HOME

layouts/_partials/header.ejs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<div class="AppHeader">
2+
<div class="bg-blue-dark border-t-8 border-green">
3+
<div class="container flex items-center flex-wrap px-4 py-1 mx-auto">
4+
<a href="/" class="w-1/4 flex-1">
5+
<div class="relative w-16 h-16">
6+
<img class="w-16 h-16 absolute pin"
7+
src="https://art.nativescript-vue.org/NativeScript-Vue-White-Green.svg"
8+
alt="NativeScript-Vue Logo">
9+
<img class="w-16 h-16 absolute pin transition-all-ease hover:opacity-0"
10+
src="https://art.nativescript-vue.org/NativeScript-Vue-Green-White.svg"
11+
alt="NativeScript-Vue Logo">
12+
</div>
13+
</a>
14+
<div class="w-auto text-center relative">
15+
<input class="w-full md:w-48 px-4 py-2 text-blue-lightest bg-blue-light rounded-full"
16+
type="search"
17+
placeholder="Search coming soon."
18+
disabled
19+
>
20+
21+
<div class="hidden absolute ml-2 mt-2">
22+
<div class="border bg-white rounded shadow w-48"></div>
23+
</div>
24+
</div>
25+
26+
<!-- Bars -->
27+
<div class="ml-4 md:hidden text-right" @click="navOpen = !navOpen">
28+
<div class="inline-block">
29+
<div class="w-6 h-2px bg-white mb-1"></div>
30+
<div class="w-6 h-2px bg-white mb-1"></div>
31+
<div class="w-6 h-2px bg-white"></div>
32+
</div>
33+
</div>
34+
35+
<!-- Nav -->
36+
<div :class="{ hidden: isMobile && !navOpen, flex: isMobile && navOpen }"
37+
class="flex-col md:flex-row w-full md:w-auto">
38+
<a href="#" class="no-underline text-blue-lightest md:ml-6 mr-4 py-4">Quick Start</a>
39+
<a href="#" class="no-underline text-blue-lightest mr-4 py-4">Guides</a>
40+
<a href="#" class="no-underline text-blue-lightest mr-4 py-4">API</a>
41+
<div class="inline text-blue-lightest mr-4 py-4 relative group">
42+
Community
43+
44+
<div class="pl-4 mt-3 md:pl-0 md:hidden group-hover:block hover:block md:absolute md:bg-white md:border md:shadow md:rounded md:pin-r">
45+
<div class="flex flex-col">
46+
<a href="#" class="no-underline text-blue-lightest md:text-blue-dark hover:bg-green hover:text-white px-4 py-2">GitHub</a>
47+
<a href="#" class="no-underline text-blue-lightest md:text-blue-dark hover:bg-green hover:text-white px-4 py-2">Slack</a>
48+
</div>
49+
</div>
50+
</div>
51+
<div class="inline text-blue-lightest py-4 relative group">
52+
<svg class="w-4 h-4 fill-current -mb-px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><path d="M20,10c0,-5.532 -4.488,-10 -10,-10c-5.509,0 -10,4.465 -10,10c0,5.522 4.477,10 10,10c5.52,0 10,-4.475 10,-10Zm-1.678,2.581l-4.01,0c0.277,-1.73 0.266,-3.497 0.002,-5.162l4.008,0c0.517,1.67 0.517,3.492 0,5.162Zm-8.322,6.064c-1.239,-1.118 -2.183,-2.803 -2.72,-4.774l5.44,0c-0.537,1.971 -1.481,3.656 -2.72,4.774Zm-3.006,-6.064c-0.29,-1.669 -0.297,-3.449 0.001,-5.162l6.01,0c0.298,1.712 0.291,3.492 0.001,5.162l-6.012,0Zm3.006,-11.225c1.353,1.221 2.24,3.022 2.718,4.773l-5.436,0c0.48,-1.76 1.37,-3.556 2.718,-4.773Zm7.804,4.773l-3.75,0c-0.441,-1.78 -1.184,-3.375 -2.173,-4.635c2.588,0.569 4.762,2.295 5.923,4.635Zm-9.685,-4.635c-0.989,1.26 -1.732,2.855 -2.173,4.635l-3.75,0c1.161,-2.34 3.335,-4.066 5.923,-4.635Zm-6.441,5.925l4.008,0c-0.264,1.665 -0.275,3.432 0.002,5.162l-4.01,0c-0.517,-1.67 -0.517,-3.492 0,-5.162Zm0.518,6.452l3.755,0c0.443,1.781 1.188,3.38 2.17,4.636c-2.602,-0.572 -4.77,-2.308 -5.925,-4.636Zm9.683,4.636c0.982,-1.256 1.727,-2.855 2.17,-4.636l3.755,0c-1.157,2.332 -3.327,4.065 -5.925,4.636Z" style="fill-rule:nonzero;"/></svg>
53+
<span class="md:hidden">Language</span>
54+
55+
<div class="pl-4 mt-3 md:pl-0 md:hidden group-hover:block hover:block md:absolute md:bg-white md:border md:shadow md:rounded md:pin-r">
56+
<div class="flex flex-col">
57+
<a href="#" class="no-underline text-blue-lightest md:text-blue-dark hover:bg-green hover:text-white px-4 py-2" @click.prevent="switchLang('en')">en</a>
58+
<a href="#" class="no-underline text-blue-lightest md:text-blue-dark hover:bg-green hover:text-white px-4 py-2" @click.prevent="switchLang('hu')">hu</a>
59+
</div>
60+
</div>
61+
</div>
62+
</div>
63+
</div>
64+
</div>
65+
66+
<!-- Mobile Docs Nav -->
67+
<!--<div class="bg-grey-lighter md:hidden">-->
68+
<!--<div class="container mx-auto p-4">-->
69+
<!--<select class="w-full p-2">-->
70+
<!--&lt;!&ndash;<option v-for="item in flat_toc" :key="item.name" :value="item.path">{{ item.name }}</option>&ndash;&gt;-->
71+
<!--</select>-->
72+
<!--</div>-->
73+
<!--</div>-->
74+
</div>

layouts/_partials/sidebar.ejs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div class="AppSidebar p-4 py-4 md:py-8">
2+
<ul class="list-reset">
3+
<!--<NavigationItem :children="toc"/>-->
4+
</ul>
5+
</div>

layouts/default.ejs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,33 @@
66
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
77
<meta http-equiv="X-UA-Compatible" content="ie=edge">
88
<title><%= sitename %></title>
9+
<link rel="stylesheet" href="/styles.css">
910
</head>
1011
<body>
11-
<%- contents %>
1212

13-
<div>
14-
<%- include('_partials/links', { posts: collections.blog }) %>
15-
<%- include('_partials/links', { posts: collections.docs }) %>
13+
<div id="app">
14+
<div class="font-sans leading-normal" :class="{'max-h-screen': modalVisible, 'overflow-hidden': modalVisible}">
15+
<!--<QuickStart />-->
16+
<%- include('_partials/header') %>
17+
18+
<div class="md:bg-docs-gradient min-h-screen">
19+
<div class="container mx-auto flex">
20+
<div class="hidden md:w-1/4 md:block">
21+
<%- include('_partials/sidebar') %>
22+
</div>
23+
<div class="w-full md:w-3/4 bg-white min-h-screen">
24+
<div class="p-4 md:p-8">
25+
<div class="markdown-body">
26+
<%- contents %>
27+
</div>
28+
</div>
29+
</div>
30+
</div>
31+
</div>
32+
</div>
1633
</div>
1734

18-
<% if(typeof contributors !== 'undefined') { %>
19-
<%- include('_partials/contributors', contributors) %>
20-
<% } %>
35+
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
36+
<script src="/main.js"></script>
2137
</body>
2238
</html>

layouts/landing.ejs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport"
6+
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
7+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8+
<title><%= sitename %></title>
9+
<link rel="stylesheet" href="/styles.css">
10+
</head>
11+
<body>
12+
13+
<div id="app">
14+
<div class="font-sans leading-normal" :class="{'max-h-screen': modalVisible, 'overflow-hidden': modalVisible}">
15+
<!--<QuickStart />-->
16+
<%- include('_partials/header') %>
17+
18+
<div class="min-h-screen">
19+
<%- contents %>
20+
</div>
21+
</div>
22+
</div>
23+
24+
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
25+
<script src="/main.js"></script>
26+
</body>
27+
</html>

layouts/no_sidebar.ejs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport"
6+
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
7+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8+
<title><%= sitename %></title>
9+
<link rel="stylesheet" href="/styles.css">
10+
</head>
11+
<body>
12+
13+
<div id="app">
14+
<div class="font-sans leading-normal" :class="{'max-h-screen': modalVisible, 'overflow-hidden': modalVisible}">
15+
<!--<QuickStart />-->
16+
<%- include('_partials/header') %>
17+
18+
<div class="min-h-screen">
19+
<div class="container mx-auto flex">
20+
<div class="w-full bg-white min-h-screen">
21+
<div class="p-4 md:p-8">
22+
<div class="markdown-body">
23+
<%- contents %>
24+
</div>
25+
26+
</div>
27+
</div>
28+
</div>
29+
</div>
30+
</div>
31+
</div>
32+
33+
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
34+
<script src="/main.js"></script>
35+
</body>
36+
</html>

0 commit comments

Comments
 (0)