Skip to content

Instantly share code, notes, and snippets.

@Jotschi
Last active February 1, 2017 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jotschi/e57feb91b45f8b72cde69a1662157b2e to your computer and use it in GitHub Desktop.
Save Jotschi/e57feb91b45f8b72cde69a1662157b2e to your computer and use it in GitHub Desktop.
Gentics Mesh Express Example
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css">
<meta charset="UTF-8">
<title>Gentics Mesh Demo</title>
<style>
.row.products > div {
height: 500px
}
</style>
</head>
<body>
<div class="container">
<h2>Gentics Mesh Silex Demo <small><a href="http://getmesh.io">getmesh.io</a></small></h2>
{% include "navigation.njk" %}
{% block content %}{% endblock %}
</div>
</body>
</html>
"use strict";
const express = require('express')
const request = require('request');
const rp = require('request-promise');
const nunjucks = require('nunjucks');
const app = express();
nunjucks.configure('views', {
autoescape: true,
express: app
});
var BASEURI = "http://admin:admin@localhost:8080/api/v1/";
/**
* Load the breadcrumb information for the root level of the project.
* @return {Promise} Promise with breadcrumb information
*/
function loadBreadcrumbData() {
let options = {
uri: BASEURI + "demo/navroot/?maxDepth=1&resolveLinks=short",
json: true
}
return rp(options).then(result => result.root.children);
}
/**
* Load a list of children for the specified node.
* @param uuid Uuid of the node
* @return {Promise} Promise with children information for the located node
*/
function loadChildren(uuid) {
let options = {
uri: BASEURI + "demo/nodes/" + uuid + "/children?expandAll=true&resolveLinks=short",
json: true
}
return rp(options).then(result => result.data);
}
// Dedicated route for the welcome page
app.get("/", (req, res) => {
loadBreadcrumbData().then(data => {
res.render('welcome.njk', {
breadcrumb: data
});
});
});
// Webroot path route which consumes all other paths in order to fetch the corresponding Gentics Mesh node and render its contents.
app.get('*', (req, res) => {
let path = req.params[0];
console.log("Handling path {" + path + "}");
// 1. Use the webroot endpoint to resolve the path to a Gentics Mesh node. The node information will later
// be used to determine which nunjucks template to use in order to render the page.
let uri = BASEURI + "demo/webroot/" + encodeURIComponent(path) + "?resolveLinks=short";
let options = {
uri: uri,
resolveWithFullResponse: true,
json: true,
// Enable direct buffer handling for the request api in order to allow binary data passthru for images.
encoding: null
}
rp(options).then(response => {
let contentType = response.headers['content-type'];
// 2. Check whether the found node represents an image. Otherwise continue with template specific code.
if (contentType.startsWith("image/")) {
res.contentType(contentType).send(response.body);
} else {
let elementJson = response.body;
let uuid = elementJson.uuid;
let schemaName = elementJson.schema.name;
let navigationPromise = loadBreadcrumbData();
switch (schemaName) {
// Check whether the loaded node is a vehicle node. In those cases a detail page should be shown.
case "vehicle":
console.log("Handling vehicle request");
navigationPromise.then(navData => {
res.render('productDetail.njk', {
'breadcrumb': navData,
'product': elementJson
});
});
break;
// Show the product list page for category nodes
case "category":
console.log("Handling category request");
let childrenPromise = loadChildren(uuid);
Promise.all([navigationPromise, childrenPromise]).then(data => {
const [navigationData, childrenData] = data;
res.render('productList.njk', {
'breadcrumb': navigationData,
'category': elementJson,
'products': childrenData
});
}).catch(err => {
console.log("Error while resolving promises {" + err.message + "}");
res.status(500).send("Oh uh, something went wrong");
});
break;
// Show 404 or error for other nodes
default:
res.status(404).send("Unknown element type for given path");
break;
}
}
}).catch(err => {
if (err.statusCode == 404) {
res.status(404).send("Page not found");
} else {
console.log("Error {" + err.message + "}");
res.status(500).send("Oh uh, something went wrong");
}
});
});
// Start the ExpressJS server on port 3000
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a href="/" class="navbar-brand">Home</a>
</div>
<ul class="nav navbar-nav">
{% for segment in breadcrumb %}
{% if segment.node.schema.name == "category" %}
<li>
<a href="{{segment.node.path}}">{{segment.node.fields.name}}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</nav>
{
"name": "mesh-express-example",
"version": "1.0.0",
"description": "Gentics Mesh Express Example",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "j.schueth@gentics.com",
"license": "ISC",
"dependencies": {
"express": "^4.14.0",
"nunjucks": "^3.0.0",
"request": "^2.79.0",
"request-promise": "^4.1.1"
}
}
{% extends "base.njk" %}
{% block content %}
<div>
<h1>{{ product.fields.name }}</h1>
<div class="row">
<div class="col-md-6">
<form name="productForm">
<div class="form-group">
<label for="name">Product Name</label>
<input type="text"
class="form-control"
id="name"
name="name"
placeholder="Name"
required
value="{{ product.fields.name}}">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control"
rows="7"
id="description"
name="description"
required
>{{ product.fields.description }}</textarea>
</div>
<div class="form-group">
<label for="sku">SKU</label>
<input type="text"
class="form-control"
id="sku"
name="sku"
placeholder="SKU"
value="{{ product.fields.SKU }}">
</div>
<div class="row">
<div class="col-sm-4 form-group">
<label for="price">Price</label>
<input type="number"
step="0.01"
min="0"
class="form-control"
id="price"
name="price"
value="{{ product.fields.price }}">
</div>
<div class="col-sm-4 form-group">
<label for="weight">Weight</label>
<input type="number"
class="form-control"
min="0"
id="weight"
name="weight"
value="{{ product.fields.weight }}">
</div>
<div class="col-sm-4 form-group">
<label for="stock">Stock Level</label>
<input type="number"
min="0"
class="form-control"
id="stock"
name="stock"
value="{{ product.fields.stocklevel }}">
</div>
</div>
</form>
</div>
<div class="col-md-6">
<img style="width: 100%;" class="img-thumbnail" src="{{ product.fields.vehicleImage.path }}"">
</div>
</div>
</div>
{% endblock %}
{% extends "base.njk" %}
{% block content %}
<div>
<h1>{{ category.fields.name }}</h1>
<p>{{ category.fields.description }}</p>
<div class="row products">
{% for product in products %}
<div class="col-xs-12 col-sm-6 col-md-4">
<div class="panel panel-default">
<div class="panel-body">
<h3>
<a href="{{ product.path }}">{{ product.fields.name }}</a>
<small>{{ product.fields.SKU }}</small>
</h3>
<a href="{{ product.path }}">
<img style="height: 200px; width: 100%;" src="{{ product.fields.vehicleImage.path }}" class="img-thumbnail">
</a>
<p>{{ product.fields.description }}</p>
<hr>
<div class="row">
<div class="col-xs-6">
<!--| number: 2 -->
<h3 style="margin: 5px 0;"><span class="label label-primary">€{{ product.fields.price }}</span></h3>
</div>
<div class="col-xs-6 text-right">
<span class="label label-default">Weight: {{ product.fields.weight }}</span><br>
<span class="label label-default">Stock: {{ product.fields.stocklevel }}</span>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
# Clone the example from github
git clone https://github.com/gentics/mesh-express-example.git
cd mesh-express-example
# Update the node dependencies
npm install
# Downlad Gentics Mesh from http://getmesh.io/Download and start it
java -jar mesh-demo-0.6.xx.jar
# Start the express server
node index.js
{% extends "base.njk" %}
{% block content %}
<div class="jumbotron">
<div class="row">
<div class="col-sm-3 text-right">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" style="max-width: 150px;" viewBox="0 0 500.000000 579.000000" preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,579.000000) scale(0.100000,-0.100000)" fill="#00a0d2" stroke="none">
<path class="gtx-logo-main" d="M2417 5780 c-21 -6 -52 -17 -70 -26 -24 -13 -2014 -1184 -2183 -1285 -43 -26 -108 -98 -136 -151 l-23 -43 -3 -1362 -2 -1362 21 -56 c44 -119 20 -102 1213 -805 598 -353 1109 -652 1135 -663 65 -30 197 -30 262 0 34 15 1874 1096 2205 1294 43 26 108 98 136 151 l23 43 3 1362 c2 1355 2 1362 -18 1417 -61 163 -257 260 -425 211 -41 -12 -278 -145 -765 -432 -774 -455 -786 -463 -829 -578 -28 -75 -28 -184 0 -260 27 -72 104 -156 176 -191 75 -37 185 -44 263 -17 30 10 240 127 466 261 227 133 414 242 418 242 3 0 5 -383 4 -851 l-3 -851 -888 -524 c-488 -288 -892 -524 -897 -524 -5 0 -409 236 -897 524 l-888 524 0 1067 0 1067 888 524 c488 288 892 524 897 524 5 0 184 -103 397 -229 258 -152 408 -235 447 -246 162 -47 339 35 417 193 20 40 24 63 24 147 0 88 -3 107 -26 156 -15 32 -44 74 -66 96 -37 37 -964 593 -1059 635 -52 22 -162 32 -217 18z"></path>
<path class="gtx-logo-dot" d="M2343 3231 c-222 -82 -310 -351 -181 -553 80 -127 249 -192 398 -154 115 30 199 99 249 206 23 48 26 68 26 155 0 89 -3 106 -28 157 -36 73 -102 139 -174 174 -76 38 -211 45 -290 15z"></path>
</g>
</svg>
</div>
<div class="col-sm-9">
<h1>Gentics Mesh Demo Application</h1>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<p>This is a basic demonstration of how to build an application to use Mesh. This example is an Silex implementation
and the source is <a href="https://github.com/gentics/mesh-silex-example">available on GitHub</a>.</p>
<p><a class="btn btn-primary btn-lg" href="http://getmesh.io/docs/beta/getting-started.html" role="button">Learn more</a></p>
</div>
</div>
</div>
{% endblock %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment