スタイリング
前章では、単純な組成だけであった。 本章では、目的とするレイアウトに近づける。機能はまだ作らない。
サンプルコードは、こちら。
組成
team_composite/serve.js
const express = require('express');
const fetch = require('node-fetch');
const app = express();
app.set("view engine", "ejs");
const port = process.env.PORT || 2000;
const inspireHost = process.env.INSPIRE_HOST || 'localhost:4000';
const productHost = process.env.PRODUCT_HOST || 'localhost:5000';
const searchHost = process.env.SEARCH_HOST || 'localhost:6000';
app.get('/', async (req, res) => {
const inspireList = await (await fetch(`http://${inspireHost}/inspire-list`)).text();
const inspireLabel = await (await fetch(`http://${inspireHost}/inspire-label`)).text();
const productList = await (await fetch(`http://${productHost}/product-list`)).text();
const searchBox = await (await fetch(`http://${searchHost}/search-box`)).text();
res.render("./index.ejs", {
inspireList: inspireList,
inspireLabel: inspireLabel,
productList: productList,
searchBox: searchBox
});
});
app.listen(port, () => {
console.log(`Team Composite app listening at http://localhost:${port}`)
});
サーバーサイドでは、各フラグメントを取得し、次のindex.ejs
の各変数に組み込む。
team_omposite/views/index.ejs
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<title>team_composite</title>
</head>
<style>
body {
margin: 5%;
}
.wrapper {
display: grid;
}
.team-search-box {
border: medium dotted red;
}
.team-product-list {
border: medium dotted blue;
}
.team-inspire-list {
border: medium dotted green;
grid-column-start: 2;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 3;
}
</style>
<body>
</body>
<div class="wrapper">
<div class="team-search-box">
<%- searchBox %>
</div>
<div class="team-product-list">
<%- productList %>
</div>
<div class="team-inspire-list">
<%- inspireLabel %>
<%- inspireList %>
</div>
</div>
</html>
フラグメント
team-search-box
http://${searchHost}/search-box
は、次のようなserve.js
で返却する。
team_composite/serve.js
const express = require('express')
const app = express()
app.set("view engine", "ejs")
const port = process.env.PORT || 6000;
app.get('/search-box', (req, res) => {
res.render('./search-box.ejs')
})
app.listen(port, () => {
console.log(`Team Search app listening at http://localhost:${port}`)
})
team_search/views/search-box.ejs
<style>
.team-search-box-button {
border: none;
background-color: inherit;
}
.team-search-box-input {
width: 50%;
}
</style>
<input placeholder="Please enter keywords ..." class="team-search-box-input"></input><button class="team-search-box-button">🔍</button>
各フラグメントのマークアップファイルに、style
をセットで書いている。
この書き方だと、他のマークアップのスタイルにも影響するやり方なので、注意が必要だ。
team-product-list
http://${productHost}/product-list
は、次のようなserve.js
で返却する。
team_product/serve.js
const express = require('express')
const app = express()
app.set("view engine", "ejs")
const port = process.env.PORT || 5000;
app.get('/product-list', (req, res) => {
res.render('./product-list.ejs', {
items: [
"Product 1",
"Product 2",
"Product 3",
]
})
})
app.listen(port, () => {
console.log(`Team Product app listening at http://localhost:${port}`)
})
team_product/views/product-list.ejs
<style>
.team-product-item {
border: medium solid;
display: inline-block;
text-align: center;
padding: 20px 0;
width: 100%;
margin: 10px 0;
}
</style>
<% for (let item of items) { %>
<%- include("./product-item.ejs", {item: item}) %>
<% } %>
team_product/views/product-item.ejs
<div class="team-product-item"><%- item %></div>
結果
その結果、次のような画面が表示される。