@nakedcreativity/cee-ms-node 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +228 -0
  2. package/package.json +18 -0
package/index.js ADDED
@@ -0,0 +1,228 @@
1
+ var express = require('express');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const _ = require('underscore');
5
+ var Liquid = require('nakedcreativity-liquid');
6
+ var cheerio = require('cheerio');
7
+
8
+
9
+
10
+ function ceems(config) {
11
+
12
+ this.app = express()
13
+
14
+ // process config and set defaults
15
+ // // set up static file hosting
16
+ this.app.use(express.static(config.assets))
17
+
18
+ this.engine = Liquid({
19
+ root: path.resolve('./views/'), // for layouts and partials
20
+ extname: '.liquid',
21
+ cache: true
22
+ });
23
+
24
+ // register liquid engine
25
+ this.app.engine('liquid', this.engine.express({
26
+ strict_variables: false,
27
+ strict_filters: true
28
+ }));
29
+ this.app.set('views', this.viewsPath());
30
+ this.app.set('view engine', 'liquid');
31
+
32
+
33
+ // register region and module tags
34
+ this.engine.registerTag('region', {
35
+ parse: function(tagToken, remainTokens) {
36
+ this.name = tagToken.args; // name
37
+ },
38
+ render: function(scope, hash) {
39
+ console.log(this.name)
40
+ var str = Liquid.evalValue('regions.'+this.name, scope);
41
+ return Promise.resolve(str);
42
+ }
43
+ });
44
+
45
+ this.engine.registerTag('module', {
46
+ parse: function(tagToken, remainTokens) {
47
+ this.name = tagToken.args; // name
48
+ },
49
+ render: function(scope, hash) {
50
+ var str = Liquid.evalValue('modules.'+this.name, scope);
51
+ return Promise.resolve(str);
52
+ }
53
+ });
54
+
55
+
56
+ this.app.listen(config.port, function () {});
57
+
58
+ this.app.use((req, res, next)=>{
59
+
60
+ if(config.response && config.response.headers){
61
+ _.each(config.response.headers, header=>{
62
+
63
+ res.header(header)
64
+
65
+ })
66
+ }
67
+ next();
68
+ });
69
+
70
+
71
+ this.app.get(/(.*)/, (req, res)=>{
72
+ this.auto(req,res);
73
+ })
74
+
75
+ }
76
+
77
+ ceems.prototype.auto = function(req, res) {
78
+
79
+ this.site = JSON.parse(fs.readFileSync('./pages/site.json', 'utf8'));
80
+ this.pages_map = _.indexBy(this.site.pages, 'url');
81
+
82
+ var start = Date.now()
83
+
84
+ if(this.pages_map[req._parsedUrl.pathname]){
85
+ var page = this.pages_map[req._parsedUrl.pathname]
86
+
87
+ if(page.redirect){
88
+ res.redirect(parseInt(page.redirect.type), page.redirect.to)
89
+ }
90
+
91
+ var page = JSON.parse(fs.readFileSync('./pages/'+page.handle+'.json', 'utf8'));
92
+
93
+ }else{
94
+ try {
95
+ var page = JSON.parse(fs.readFileSync('./drafts/'+req._parsedUrl.pathname.replace('/drafts/','')+'.json', 'utf8'));
96
+ }catch (error){
97
+ res.status(404).send('Sorry, this page does not exist');
98
+ }
99
+ }
100
+
101
+
102
+ // get any external data, and save this into the page
103
+ _.each(page.external, function(ext, key){
104
+
105
+ try {
106
+ page.external[key].data = JSON.parse(fs.readFileSync('./'+ext.file, 'utf8'));
107
+ }catch(error){
108
+ console.log(error)
109
+ }
110
+
111
+ })
112
+
113
+ var renderedRegions = {}
114
+ var jobs = []
115
+
116
+ // load page data
117
+ _.each(page.regions, function(region, key){
118
+
119
+ renderedRegions[key] = []
120
+ _.each(region.modules, function(module, index){
121
+
122
+ var moduleTemplate = fs.readFileSync('./views/'+module.type+'.liquid');
123
+
124
+ jobs.push(new Promise((resolve,reject) => {
125
+
126
+ // to-do: we need to give module access to entire page object, and therefore the 'sitemap' and other site information
127
+ var scope = module.content
128
+ scope.page = page
129
+ scope.site = this.site.site
130
+ scope.pages = this.site.pages
131
+
132
+ this.engine.parseAndRender(moduleTemplate, scope)
133
+ .then(function(html){
134
+
135
+
136
+ if(req.query.edit != null){
137
+ var $ = cheerio.load(html);
138
+
139
+ $.root().children().attr('data-module-type', module.type);
140
+ $.root().children().attr('data-module-id', module.id);
141
+
142
+ html = $.html()
143
+ }
144
+
145
+ renderedRegions[key][index] = html
146
+ return resolve();
147
+ });
148
+ }))
149
+
150
+ }, this)
151
+ }, this)
152
+
153
+ // loop through each module not in a region and generate HTML
154
+ _.each(page.modules, function(module, key){
155
+
156
+ var moduleTemplate = fs.readFileSync('./views/'+module.type+'.liquid');
157
+
158
+ jobs.push(new Promise((resolve,reject) => {
159
+
160
+ // we need to give module access to entire page object, and therefore the 'sitemap' and other site information
161
+ var scope = module.content
162
+ scope.page = page
163
+ scope.site = this.site.site
164
+ scope.pages = this.site.pages
165
+
166
+ this.engine.parseAndRender(moduleTemplate, scope)
167
+ .then(function(html){
168
+ //console.log(html)
169
+
170
+ if(req.query.edit != null){
171
+ var $ = cheerio.load(html);
172
+ $.root().children().attr('data-module-type', module.type);
173
+ $.root().children().attr('data-module-id', module.id);
174
+ //console.log($.root().children())
175
+
176
+ html = $.html()
177
+ }
178
+
179
+ page.modules[key] = html
180
+ return resolve();
181
+
182
+ });
183
+ }))
184
+
185
+ }, this)
186
+
187
+ Promise.all(jobs).then(html =>{
188
+
189
+ // map / reduce? look at _
190
+ _.each(renderedRegions, function(region, key){
191
+ page.regions[key] = ''
192
+ _.each(region, function(html){
193
+ page.regions[key] += html
194
+ })
195
+ })
196
+
197
+ res.render(page.template, page, function(err, html){
198
+ if(err){
199
+ console.log(err)
200
+ }
201
+ var finish = Date.now()
202
+ console.log(finish - start, 'render time')
203
+ console.log('..................')
204
+
205
+ res.send(html)
206
+ })
207
+
208
+ }, reason => {
209
+ console.log(reason)
210
+ }).catch(error=>{
211
+ console.log(error)
212
+ res.status(500).send('Internal server error');
213
+ })
214
+ }
215
+
216
+ ceems.prototype.init = function(){
217
+
218
+ // needs to be dealt with on each request, or results cache in someway
219
+
220
+
221
+
222
+ }
223
+
224
+ ceems.prototype.viewsPath = function(){
225
+ return './views/'
226
+ }
227
+
228
+ module.exports = ceems;
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@nakedcreativity/cee-ms-node",
3
+ "version": "0.1.0",
4
+ "description": "Cee.ms for Node.js",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "author": "Naked Creativity",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "cheerio": "^0.22.0",
13
+ "express": "^4.14.0",
14
+ "nakedcreativity-liquid": "^1.2.6",
15
+ "underscore": "^1.8.3"
16
+ },
17
+ "devDependencies": {}
18
+ }