2023年12月31日日曜日

Cozy Web/グリッド内カードのカスタマイズ

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

前回はWebフロントエンド・フレームワークBootstrapの上でグリッド表示を行いました。

今回はグリッド内に配置されるカードをカスタマイズする方法について説明します。

HelloGrid

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

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

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

準備

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

モデル

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

  1. * entity    
  2. ** product  
  3. *** features    
  4. table=product  
  5. *** attributes    
  6. | Name  | Type   | Multiplicity |  
  7. |-------+--------+--------------|  
  8. | id    | token  |            1 |  
  9. | name  | string |            1 |  
  10. | price | int    |            1 |  

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

webapp.conf

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

またthemeにbootstrap-gridを設定します。この設定により一覧表示がグリッドで表示されます。

ここまでが前回の設定です。

  1. extend: bootstrap5  
  2. theme: bootstrap-grid  

今回はグリッドの表示方法をカスタマイズします。

このためにwebapp.confに以下のようにrender.card_kind_in_gridを設定します。

render.card_kind_in_gridに"grid"を指定しているので、card__gridという名前のウィジェットがグリッド内のカードの表示に使用されます。

  1. extend: bootstrap5  
  2. theme: bootstrap-grid  
  3. render.card_kind_in_grid: "grid"  

カードの表示内容の設定

グリッド内にカードを表示するときに使用するウィジェットcard_gridを作成します。

以下のJade形式の card__grid.jade 作成し、WEB-INF/widgets配下に配置します。

  1. -@val card: ViewCard  
  2. div.card  
  3.   div.card-header  
  4.     h4.card-title  
  5.       =card.header  

ファイル名card__grid.jadeの「card」はウィジェット種別を表しこの場合はカードを示します。「__」の後のgridはウィジェットの名前を表します。

カードを記述するDIV要素以下をカードの部品として定義しています。部品内ではHTMLの要素を自由に使うことができます。

部品内のHTML要素ではBootstrapで定義されているcard, card-header, card-titleといったクラス属性を指定しているので、Bootstrapによって適切な表示が行われます。

また、カードの表示に必要な情報はViewCardオブジェクトとして渡されてくるので、ここから必要な情報を取り出してウィジェット内のHTML要素に埋め込んでいきます。ここではカードのヘッダ情報をH4要素に入れています。

グリッド表示

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

Webブラウザ

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

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

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

  1. <?xml version="1.0"?>  
  2. <!DOCTYPE html>  
  3. <html lang="ja">  
  4.   <head>  
  5.     <meta charset="utf-8"/>  
  6.     <meta content="width=device-width, initial-scale=1" name="viewport"/>  
  7.     <link crossorigin="anonymous" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"/>  
  8.     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css"/>  
  9.     <style>  
  10.       .card a {  
  11.       color: inherit;  
  12.       text-decoration: none;  
  13.       }  
  14.       .card:hover {  
  15.       background-color: #f8f9fa;  
  16.       border-color: #007bff;  
  17.       }  
  18.     </style>  
  19.   </head>  
  20.   <body>  
  21.     <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"/>  
  22.     <nav class="navbar navbar-light bg-primary">  
  23.       <div class="container-fluid">  
  24.         <span class="navbar-brand mb-0 h1">Cozy Web</span>  
  25.       </div>  
  26.     </nav>  
  27.     <nav class="navbar navbar-expand-lg navbar-light bg-light">  
  28.       <div class="container-fluid">  
  29.         <a class="navbar-brand" href="#">Navbar</a>  
  30.         <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">  
  31.           <span class="navbar-toggler-icon"/>  
  32.         </button>  
  33.         <div class="collapse navbar-collapse" id="navbarNav">  
  34.           <ul class="navbar-nav">  
  35.             <li class="nav-item">  
  36.               <a class="nav-link active" aria-current="page" href="#">Home</a>  
  37.             </li>  
  38.             <li class="nav-item">  
  39.               <a class="nav-link" href="#">Features</a>  
  40.             </li>  
  41.             <li class="nav-item">  
  42.               <a class="nav-link" href="#">Pricing</a>  
  43.             </li>  
  44.             <li class="nav-item">  
  45.               <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>  
  46.             </li>  
  47.           </ul>  
  48.         </div>  
  49.       </div>  
  50.     </nav>  
  51.     <div class="container">  
  52.       <div class="row">  
  53.         <div class="col-12 col-sm-6 col-md-3 col-lg-2 col-xl-1">  
  54.           <div class="card">  
  55.             <div class="card-header">  
  56.               <h4 class="card-title">  
  57.           Apple  
  58.         </h4>  
  59.             </div>  
  60.           </div>  
  61.         </div>  
  62.         <div class="col-12 col-sm-6 col-md-3 col-lg-2 col-xl-1">  
  63.           <div class="card">  
  64.             <div class="card-header">  
  65.               <h4 class="card-title">  
  66.           Orange  
  67.         </h4>  
  68.             </div>  
  69.           </div>  
  70.         </div>  
  71.         <div class="col-12 col-sm-6 col-md-3 col-lg-2 col-xl-1">  
  72.           <div class="card">  
  73.             <div class="card-header">  
  74.               <h4 class="card-title">  
  75.           Peach  
  76.         </h4>  
  77.             </div>  
  78.           </div>  
  79.         </div>  
  80.         <div class="col-12 col-sm-6 col-md-3 col-lg-2 col-xl-1">  
  81.           <div class="card">  
  82.             <div class="card-header">  
  83.               <h4 class="card-title">  
  84.           Berry  
  85.         </h4>  
  86.             </div>  
  87.           </div>  
  88.         </div>  
  89.       </div>  
  90.     </div>  
  91.     <nav class="navbar navbar-light bg-secondary">  
  92.       <span>Cozy Web</span>  
  93.     </nav>  
  94.   </body>  
  95. </html>  

前回のグリッド表示ではカード部分は以下のHTML断片になっていました。

  1. <div class="card">  
  2.   <a href="product/1.html" class="">  
  3.     <img src="assets/img/no-image-icon.png" class="card-img-top"/>  
  4.     <div class="card-header">  
  5.       <h4 class="card-title">Apple</h4>  
  6.     </div>  
  7.   </a>  
  8. </div>  

今回は、以下のHTML断片になっており、グリッド内のカードはcard__grid.jadeで定義したものが使用されています。

  1.   <div class="card">  
  2.     <div class="card-header">  
  3.       <h4 class="card-title">  
  4.   Apple  
  5. </h4>  
  6.     </div>  
  7.   </div>  

まとめ

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

今回はBootstrapによるレスポンシブル・デザインによるグリッド表示のカードをカスタマイズする方法について説明しました。

モデルの定義とカスタマイズしたカードの定義以外はほとんどノープログラミングでレスポンシブルなWebアプリケーションの作成ができることを確認することができました。

諸元

Cozy
0.0.16