2023年11月30日木曜日

Cozy Web/グリッド

モデル駆動開発のエコシステムのキーパーツとして、Webアプリケーション・フレームワークのCozy Webを紹介しています。

数回に渡りリソースの一覧表示の方法について見てきました。その一環でグリッドとカードによる一覧表示を取り上げます。グリッドとカードによる覧表表示はHTMLの標準機能では用意されていないので、この機能をサポートしているWebフロントエンド・フレームワークBootstrapを導入し、その上でグリッドとカードによるリソースの一覧表示を行うことにします。

HelloGrid

リソースのグリッド表示を行うHelloGridを作成します。

HelloGridはBootstrap 5を使ってグリッド表示を行います。

Cozy Web/Webライブラリで紹介したWebライブラリ機能を使用してBootstrap 5をサポートするBootstrap5ライブラリを使用します。Cozy Web/Webライブラリで紹介したWebライブラリ機能を使用してBootstrap 5をサポートするBootstrap5ライブラリを使用します。

準備

cozyを起動するディレクトリのwebappsディレクトリに、アプリケーションのホームディレクトリとなるHelloGridを作成します。

モデル

WEB-INF/models/model.orgにアプリケーションで使用するモデルが定義します。これは前回まで使用していたHelloResourceと同じ設定です。

* entity  
** product
*** features  
table=product
*** attributes  
| Name  | Type   | Multiplicity |
|-------+--------+--------------|
| id    | token  |            1 |
| name  | string |            1 |
| price | int    |            1 |

エンティティproductを定義しており、Webのリソースproductとなります。

webapp.conf

ホームディレクトリのWEB-INFディレクトリ配下にwebapp.confを配置し、Bootstrap5ライブラリの名前である「bootstrap5」をextend属性に設定します。この設定を行うことで、Bootstrap5ライブラリがWebアプリケーションのベースとして設定されます。

extend: bootstrap5

一覧表示

CozyのWebライブラリBootstrap5はデフォルトでは、tableタグを使った一覧表示を行います。

Webブラウザ

前回と同様にproductリソースに対するアクセスを行います。

http://localhost:8080/web/HelloGrid/product

Cozy Web/Webライブラリで説明したとおり、WebライブラリBootstrapでは、ナビゲーションバーやヘッダー、フッターを使用した画面レイアウトになります。Cozy Web/Webライブラリで説明したとおり、WebライブラリBootstrapでは、ナビゲーションバーやヘッダー、フッターを使用した画面レイアウトになります。

画面内のコンテンツの部分にBootstrapによって綺麗にレイアウトされた表が表示されました。

HTML

webページの表示のために出力されたHTMLは以下になります。

tableタグにはBootstrap用のclass属性が設定されているため、Bootstrap標準の綺麗な表が出力されます。

<?xml version="1.0"?>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8"/>
    <meta content="width=device-width, initial-scale=1" name="viewport"/>
    <link crossorigin="anonymous" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"/>
    <style>
      .card a {
      color: inherit;
      text-decoration: none;
      }
      .card:hover {
      background-color: #f8f9fa;
      border-color: #007bff;
      }
    </style>
  </head>
  <body>
    <script crossorigin="anonymous" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"/>
    <nav class="navbar navbar-light bg-primary">
      <div class="container-fluid">
        <span class="navbar-brand mb-0 h1">Cozy Web</span>
      </div>
    </nav>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <div class="container-fluid">
        <a class="navbar-brand" href="#">Navbar</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"/>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Features</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Pricing</a>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
            </li>
          </ul>
        </div>
      </div>
    </nav>
    <div class="table-responsive">
      <table class="table">
        <caption class="">product</caption>
        <thead class="">
          <tr class="">
            <th class="" scope="col">Id</th>
            <th class="" scope="col">Name</th>
            <th class="" scope="col">Price</th>
          </tr>
        </thead>
        <tbody class="">
          <tr data-href="product/1.html">
            <td class="">1</td>
            <td class="">Apple</td>
            <td class="">300</td>
          </tr>
          <tr data-href="product/2.html">
            <td class="">2</td>
            <td class="">Orange</td>
            <td class="">350</td>
          </tr>
          <tr data-href="product/3.html">
            <td class="">3</td>
            <td class="">Peach</td>
            <td class="">400</td>
          </tr>
          <tr data-href="product/4.html">
            <td class="">4</td>
            <td class="">Berry</td>
            <td class="">450</td>
          </tr>
        </tbody>
      </table>
    </div>
    <nav class="navbar navbar-light bg-secondary">
      <span>Cozy Web</span>
    </nav>
  </body>
</html>

グリッド

それでは、グリッド表示を行います。

webapp.conf

Bootstrapアプリケーションの一覧表示のデフォルト設定をwebapp.confに設定することができます。

webapp.confのthemeにテーマbootstrap-gridを設定します。

テーマbootstrap-gridは一覧表示のデフォルト設定をグリッドにしたテーマです。

extend: bootstrap5
theme: bootstrap-grid

Webブラウザ

productリソースに対するアクセスを行います。

http://localhost:8080/web/HelloGrid/product

表示結果は以下になります。

無事Bootstrapのグリッド表示になります。グリッド内にはリソースの内容を記述するカードが表示されています。

デフォルトでは、カード内にはリソースの内容を表す画像どリソースの名前が表示されます。productでは画像の情報は持っていないので、画像なしを示す画像が表示されています。

Bootstrapのグリッドは画面サイズを変えても適切にレイアウトが行われます。先ほどのWebページの横幅を小さく縮めたWebページが以下になります。

HTML

webページの表示のために出力されたHTMLは以下になります。

グリッド内のカードはclass属性にcardが設定されたdevタグで記述されています。

<?xml version="1.0"?>
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8"/>
    <meta content="width=device-width, initial-scale=1" name="viewport"/>
    <link crossorigin="anonymous" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"/>
    <style>
      .card a {
      color: inherit;
      text-decoration: none;
      }
      .card:hover {
      background-color: #f8f9fa;
      border-color: #007bff;
      }
    </style>
  </head>
  <body>
    <script crossorigin="anonymous" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"/>
    <nav class="navbar navbar-light bg-primary">
      <div class="container-fluid">
        <span class="navbar-brand mb-0 h1">Cozy Web</span>
      </div>
    </nav>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <div class="container-fluid">
        <a class="navbar-brand" href="#">Navbar</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"/>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Features</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Pricing</a>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
            </li>
          </ul>
        </div>
      </div>
    </nav>
    <div class="container">
      <div class="row">
        <div class="col-12 col-sm-6 col-md-3 col-lg-2 col-xl-1">
          <div class="card">
            <a href="product/1.html" class="">
              <img src="assets/img/no-image-icon.png" class="card-img-top"/>
              <div class="card-header">
                <h4 class="card-title">Apple</h4>
              </div>
            </a>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-md-3 col-lg-2 col-xl-1">
          <div class="card">
            <a href="product/2.html" class="">
              <img src="assets/img/no-image-icon.png" class="card-img-top"/>
              <div class="card-header">
                <h4 class="card-title">Orange</h4>
              </div>
            </a>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-md-3 col-lg-2 col-xl-1">
          <div class="card">
            <a href="product/3.html" class="">
              <img src="assets/img/no-image-icon.png" class="card-img-top"/>
              <div class="card-header">
                <h4 class="card-title">Peach</h4>
              </div>
            </a>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-md-3 col-lg-2 col-xl-1">
          <div class="card">
            <a href="product/4.html" class="">
              <img src="assets/img/no-image-icon.png" class="card-img-top"/>
              <div class="card-header">
                <h4 class="card-title">Berry</h4>
              </div>
            </a>
          </div>
        </div>
      </div>
    </div>
    <nav class="navbar navbar-light bg-secondary">
      <span>Cozy Web</span>
    </nav>
  </body>
</html>

まとめ

前回まではCozy Webでリソースの定義をすることで、Webアプリケーションが簡単に作成できることを説明しました。

今回は画面の表示方法のカスタマイズとして、グリッド表示を取り上げました。

テーマの設定のみで一覧表示をtableタグによる表からBootstrapならではのグリッド表示にすることができました。また、グリッド表示はBootstrapの機能により画面サイズに従って適切なレイアウトが行われることが確認できました。

モデルの定義以外はほとんどノープログラミングでWebアプリケーションの作成ができることが分かりました。

次回はグリッド表示のカスタマイズ方法について取り上げる予定です。

諸元

Cozy
0.0.15