Skip to content

Commit 8c85f09

Browse files
committed
Enable layouts inheritance
1 parent f84350f commit 8c85f09

8 files changed

Lines changed: 189 additions & 209 deletions

File tree

build/tasks/app-pages.js

Lines changed: 100 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,44 @@ var path = require('path');
22
var glob = require('glob');
33
var fs = require('fs-extra');
44
var through = require('through2');
5+
var File = require('vinyl');
6+
var StringDecoder = require('string_decoder').StringDecoder;
57
var extend = require('util')._extend;
68

9+
var frontMatter = require('front-matter');
10+
var handlebars = require('handlebars');
11+
var handlebarsRegistrar = require('handlebars-registrar');
12+
713
var config = require('../config');
14+
var partials = {};
815

916
module.exports.task = function(gulp, plugins, paths) {
1017

11-
// Handlebars engine
12-
var handlebars = new require('handlebars');
13-
var handlebarsRegistrar = require('handlebars-registrar');
1418

1519
// Register handlebars engine helpers and partials
1620
handlebarsRegistrar(handlebars, {
1721
helpers: paths.app.helpers,
1822
partials: paths.app.templates,
19-
parsePartialName: function (file) {
20-
return file.shortPath;
23+
parsePartialName: function (partial) {
24+
25+
// Save in partials vinyl registry
26+
partials[partial.shortPath] = new File({
27+
cwd: partial.cwd,
28+
path: partial.path,
29+
base: path.basename(partial.path),
30+
contents: fs.readFileSync(partial.path)
31+
});
32+
33+
return partial.shortPath;
2134
},
35+
bustCache: true,
2236
});
2337

38+
2439
gulp.src(paths.app.pages)
25-
// Frontmatter
26-
.pipe(plugins.frontMatter())
2740
// Render pages
2841
.pipe(through.obj(function (file, enc, cb) {
29-
// Page render result
30-
var pageRes = "";
31-
32-
// Get context from _context.js files and frontmatter
33-
var context = getPageContext(file);
34-
context = extend(context, file.frontMatter);
35-
36-
// Compile template
37-
var template = handlebars.compile(String(file.contents));
38-
var templateRes = template(context);
39-
40-
// Layout processing
41-
var layout = context.layout || null;
42-
43-
// If the layout exists, render it with template inside
44-
if (layout && handlebars.partials[layout]) {
45-
var layoutData = extend(context, {
46-
body: templateRes
47-
});
48-
49-
// Render layout with given context and content
50-
var layoutRes = handlebars.partials[layout](layoutData);
51-
52-
pageRes = layoutRes;
53-
}
54-
// Return rendered template
55-
else {
56-
pageRes = templateRes;
57-
}
58-
59-
file.contents = new Buffer(pageRes);
42+
file.contents = new Buffer(renderTemplate(file));
6043

6144
this.push(file);
6245
cb();
@@ -75,21 +58,99 @@ module.exports.task = function(gulp, plugins, paths) {
7558

7659
// Output
7760
.pipe(gulp.dest(config.destDir));
61+
7862
};
7963

8064

8165
/********************************************
8266
* Utils
8367
*********************************************/
8468

69+
function renderTemplate(file, options) {
70+
71+
options = options || {};
72+
73+
// Set file frontMatter
74+
file = setFrontMatter(file);
75+
76+
// Get context from _context.js files and frontmatter
77+
var contextExternal = getPageContextExternal(file);
78+
79+
// Frontmatter context
80+
var contextTemplate = file.frontMatter || {};
81+
82+
// Inherited context from child
83+
var contextInherited = options.contextInherited || {};
84+
85+
// Result context
86+
var context = extend({}, contextExternal);
87+
context = extend(context, contextTemplate);
88+
context = extend(context, contextInherited);
89+
90+
// Page render result
91+
var pageRes = "";
92+
93+
// Compile template
94+
var template = handlebars.compile(String(file.contents));
95+
var templateRes = template(context);
96+
97+
// Layout processing
98+
var layout = context.layout || null;
99+
100+
// If the layout exists, render it with template inside
101+
if (layout && partials[layout] && handlebars.partials[layout]) {
102+
103+
// New instance of context
104+
var layoutData = extend({}, context);
105+
106+
// Add body to context
107+
layoutData = extend(layoutData, {
108+
body: templateRes
109+
});
110+
111+
// Remove layout parameter from inhereted context
112+
delete layoutData.layout;
113+
114+
// New vinyl file based on partail vinyl
115+
var layoutFile = new File(partials[layout]);
116+
117+
// Call recursively render template again
118+
pageRes = renderTemplate(layoutFile, {
119+
contextInherited: layoutData
120+
});
121+
}
122+
// Return rendered template
123+
else {
124+
pageRes = templateRes;
125+
}
126+
127+
return pageRes;
128+
}
129+
130+
131+
/*
132+
Frontmatter file
133+
*/
134+
function setFrontMatter(file) {
135+
// Read content from front matter
136+
var content = frontMatter(file.contents.toString('utf8'));
137+
138+
// var res = new Buffer(content.body);
139+
file.contents = new Buffer(content.body);
140+
file.frontMatter = content.attributes;
141+
142+
return file;
143+
}
144+
145+
85146
/*
86147
This function returns context of current page
87148
which is root context extended by all contexts untill
88149
current level context
89150
*/
90151

91152

92-
function getPageContext(file) {
153+
function getPageContextExternal(file) {
93154

94155
var context = {};
95156

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"homepage": "https://github.com/modularcode/modular-admin-html",
1515
"dependencies": {},
1616
"devDependencies": {
17+
"front-matter": "^2.0.5",
1718
"fs-extra": "^0.26.4",
1819
"glob": "^5.0.14",
1920
"gulp": "^3.9.0",
@@ -37,7 +38,8 @@
3738
"handlebars-layouts": "^3.1.0",
3839
"handlebars-registrar": "^1.5.2",
3940
"main-bower-files": "^2.9.0",
40-
"through2": "^2.0.0"
41+
"through2": "^2.0.0",
42+
"vinyl": "^1.1.0"
4143
},
4244
"scripts": {
4345
"gulp": "gulp --gulpfile build/gulpfile.js",

src/_context.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/_main-layout.hbs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
title: ModularAdmin - Free Dashboard Theme | HTML Version
3+
---
4+
<!doctype html>
5+
<html class="no-js" lang="en">
6+
<head>
7+
<meta charset="utf-8">
8+
<meta http-equiv="x-ua-compatible" content="ie=edge">
9+
<title>
10+
{{title}}
11+
</title>
12+
<meta name="description" content="">
13+
<meta name="viewport" content="width=device-width, initial-scale=1">
14+
15+
<link rel="apple-touch-icon" href="apple-touch-icon.png">
16+
<!-- Place favicon.ico in the root directory -->
17+
18+
<link rel="stylesheet" href="css/vendor.css">
19+
20+
<!-- Theme initialization -->
21+
<script>
22+
var themeSettings = (localStorage.getItem('themeSettings')) ? JSON.parse(localStorage.getItem('themeSettings')) : {};
23+
var themeName = themeSettings.themeName || '';
24+
25+
if (themeName) {
26+
document.write('<link rel="stylesheet" id="theme-style" href="css/app-' + themeName + '.css">');
27+
}
28+
else {
29+
document.write('<link rel="stylesheet" id="theme-style" href="css/app.css">');
30+
}
31+
</script>
32+
</head>
33+
<body>
34+
{{{body}}}
35+
<!-- Reference block for JS -->
36+
<div class="ref" id="ref">
37+
<div class="color-primary"></div>
38+
<div class="chart">
39+
<div class="color-primary"></div>
40+
<div class="color-secondary"></div>
41+
</div>
42+
</div>
43+
<script src="js/vendor.js"></script>
44+
<script src="js/app.js"></script>
45+
</body>
46+
</html>

src/app/_common/header/nav/notifications/notifications.hbs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<li>
1515
<a href="" class="notification-item">
1616
<div class="img-col">
17-
<div class="img" style="background-image: url('{{images.faces.[0]}}')"></div>
17+
<div class="img" style="background-image: url('assets/faces/3.jpg')"></div>
1818
</div>
1919
<div class="body-col">
2020
<p>
@@ -27,7 +27,7 @@
2727
<li>
2828
<a href="" class="notification-item">
2929
<div class="img-col">
30-
<div class="img" style="background-image: url('{{images.faces.[1]}}')"></div>
30+
<div class="img" style="background-image: url('assets/faces/5.jpg')"></div>
3131
</div>
3232
<div class="body-col">
3333
<p>
@@ -40,7 +40,7 @@
4040
<li>
4141
<a href="" class="notification-item">
4242
<div class="img-col">
43-
<div class="img" style="background-image: url('{{images.faces.[2]}}')"></div>
43+
<div class="img" style="background-image: url('assets/faces/8.jpg')"></div>
4444
</div>
4545
<div class="body-col">
4646
<p>

src/app/app-blank-layout.hbs

Lines changed: 9 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,9 @@
1-
<!doctype html>
2-
<html class="no-js" lang="en">
3-
<head>
4-
<meta charset="utf-8">
5-
<meta http-equiv="x-ua-compatible" content="ie=edge">
6-
<title>
7-
{{title}}
8-
</title>
9-
<meta name="description" content="">
10-
<meta name="viewport" content="width=device-width, initial-scale=1">
11-
12-
<link rel="apple-touch-icon" href="apple-touch-icon.png">
13-
<!-- Place favicon.ico in the root directory -->
14-
15-
<link rel="stylesheet" href="css/vendor.css">
16-
17-
<!-- Theme initialization -->
18-
<script>
19-
var themeSettings = (localStorage.getItem('themeSettings')) ? JSON.parse(localStorage.getItem('themeSettings')) : {};
20-
var themeName = themeSettings.themeName || '';
21-
22-
if (themeName) {
23-
document.write('<link rel="stylesheet" id="theme-style" href="css/app-' + themeName + '.css">');
24-
}
25-
else {
26-
document.write('<link rel="stylesheet" id="theme-style" href="css/app.css">');
27-
}
28-
</script>
29-
</head>
30-
<body>
31-
<div class="app blank sidebar-opened">
32-
{{!-- Content section --}}
33-
<article class="content">
34-
{{{body}}}
35-
</article>
36-
</div>
37-
<!-- Reference block for JS -->
38-
<div class="ref" id="ref">
39-
<div class="color-primary"></div>
40-
</div>
41-
<script src="js/vendor.js"></script>
42-
<script src="js/app.js"></script>
43-
</body>
44-
</html>
1+
---
2+
layout: _main-layout
3+
---
4+
<div class="app blank sidebar-opened">
5+
{{!-- Content section --}}
6+
<article class="content">
7+
{{{body}}}
8+
</article>
9+
</div>

0 commit comments

Comments
 (0)