スタイリング

前章では、単純な組成だけであった。 本章では、目的とするレイアウトに近づける。機能はまだ作らない。

サンプルコードは、こちら

組成

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>

フラグメント

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>

結果

その結果、次のような画面が表示される。

styling_server_side_composition_tutorial
Fig. 113 styling_server_side_composition_tutorial

results matching ""

    No results matching ""