Layout development
Once you have built one or more podlets, you will want to be able to test them in the more realistic context of a layout server, thereby allowing you to see the complete page and make sure all the pieces work together correctly.
The following examples show a somewhat contrived multi-podlet and layout setup in which our layout composes together a header, a navigation area, some content and a footer.
Sample podlets
Example: header
Create a folder /podlets/header
with a file index.js
inside to hold the following podlet code.
import Podlet from "@podium/podlet";
import express from "express";
const app = express();
const podlet = new Podlet({
name: "header",
version: "1.0.0",
development: false,
});
app.use(podlet.middleware());
app.get("/manifest.json", (req, res) => {
res.json(podlet);
});
app.get("/", (req, res) => {
res.podiumSend(`<header>The Best Podium page ever</header>`);
});
app.listen(7001);
Example: navigation bar
Create a folder /podlets/navigation
with a file index.js
inside to hold the following podlet code.
import Podlet from "@podium/podlet";
import express from "express";
const app = express();
const podlet = new Podlet({
name: "navigation",
version: "1.0.0",
development: false,
});
app.use(podlet.middleware());
app.get("/manifest.json", (req, res) => {
res.json(podlet);
});
app.get("/", (req, res) => {
res.podiumSend(`<nav>
<ul>
<li><a href="/home">home</a></li>
<li><a href="/blog">blog</a></li>
<li><a href="/about">about</a></li>
<li><a href="/contact">contact</a></li>
</ul>
</nav>`);
});
app.listen(7002);
Example: main home page content
Create a folder /podlets/home
with a file index.js
inside to hold the following podlet code.
import Podlet from "@podium/podlet";
import express from "express";
const app = express();
const podlet = new Podlet({
name: "homeContent",
version: "1.0.0",
development: false,
});
app.use(podlet.middleware());
app.get("/manifest.json", (req, res) => {
res.json(podlet);
});
app.get("/", (req, res) => {
res.podiumSend(`<section>Welcome to my Podium home page</section>`);
});
app.listen(7003);
Example: page footer
Create a folder /podlets/footer
with a file index.js
inside to hold the following podlet code.
import Podlet from "@podium/podlet";
import express from "express";
const app = express();
const podlet = new Podlet({
name: "footer",
version: "1.0.0",
development: false,
});
app.use(podlet.middleware());
app.get("/manifest.json", (req, res) => {
res.json(podlet);
});
app.get("/", (req, res) => {
res.podiumSend(`<footer>© 2018 - the Podium team</footer>`);
});
app.listen(7004);
Sample layout
Example: the /home layout
Create a folder /layouts/home
. Create a file index.js
inside this folder to hold the following layout code.
import Layout from "@podium/layout";
import express from "express";
const app = express();
const layout = new Layout({
name: "homePage",
pathname: "/home",
});
const headerClient = layout.client.register({
name: "header",
uri: "http://localhost:7001/manifest.json",
});
const navigationClient = layout.client.register({
name: "navigation",
uri: "http://localhost:7002/manifest.json",
});
const contentClient = layout.client.register({
name: "content",
uri: "http://localhost:7003/manifest.json",
});
const footerClient = layout.client.register({
name: "footer",
uri: "http://localhost:7004/manifest.json",
});
app.use(layout.pathname(), layout.middleware());
app.get(layout.pathname(), async (req, res) => {
const incoming = res.locals.podium;
const [header, navigation, content, footer] = await Promise.all([
headerClient.fetch(incoming),
navigationClient.fetch(incoming),
contentClient.fetch(incoming),
footerClient.fetch(incoming),
]);
incoming.view.title = "Podium example - home";
res.podiumSend(`
<section>${header}</section>
<section>${navigation}</section>
<section>${content}</section>
<section>${footer}</section>
`);
});
app.listen(7000);
Running podlets and layout together
Because each podlet and the layout have been configured to run on different ports you can safely start them all up together.
node podlets/header
node podlets/navigation
node podlets/home
node podlets/footer
We can now start up our /home
layout to consume and display our podlet content.
node layouts/home
Our layout has been configured to run on port 7000
so we should now be able to visit the url http://localhost:7000/home
in a browser and see header
, navigation
, home page
and footer
content composed together.
Improving the development experience
The setup described above is a manual process requiring a number of repetitive operations by the developer to start up, restart or shut down processes. What follows are several suggestions for improving on this.
using forever
One fairly simple way to manage all your podlets and layouts at once is to use a tool called forever which is available on npm
.
Example: install forever
npm i -g forever
Forever
allows you to pass it some json
configuration describing your setup and have it manage the processes
Example: forever json configuration file
[
{
"uid": "header",
"append": true,
"watch": true,
"script": "index.js",
"sourceDir": "/path/to/podlets/header"
},
{
"uid": "navigation",
"append": true,
"watch": true,
"script": "index.js",
"sourceDir": "/path/to/podlets/navigation"
},
{
"uid": "home",
"append": true,
"watch": true,
"script": "index.js",
"sourceDir": "/path/to/podlets/home"
},
{
"uid": "footer",
"append": true,
"watch": true,
"script": "index.js",
"sourceDir": "/path/to/podlets/footer"
},
{
"uid": "homePage",
"append": true,
"watch": true,
"script": "index.js",
"sourceDir": "/path/to/layouts/home"
}
]
You can then pass the configuration file to forever
to start everything up at once.
Example: running forever
forever start /path/to/development.json
Notice that every service has been configured to run in watch mode meaning that they will be automatically restarted any time a file change is detected.
You can read more about forever here.
using pm2
A great alternative to forever is pm2. Pm2 can also take a configuration file in json
format, can aggregate logs, run services in watch mode, has great docs and more.