QGIS データを Web で表示 #7 - QWC2（続々）

QGIS で作成したデータ（"プロジェクト"）を Web ページで表示する方法について、ノウハウを共有します。

前回までに QGIS Server を設置し、QWC2 (QGIS Client 2) によって QGIS プロジェクトを表示する Web 地図アプリを作成し、MapCache を使って実用に耐えるパフォーマンスを確保しました。

- [QGIS データを Web で表示 #3 - QGIS Server](https://qiita.com/softark/items/c1da4f9a52e6727a5e97)
- [QGIS データを Web で表示 #4 - QWC2](https://qiita.com/softark/items/88ac73163cff278063a3)
- [QGIS データを Web で表示 #5 - QWC2（続）](https://qiita.com/softark/items/9d172c9cd6447d13ff0d)
- [QGIS データを Web で表示 #6 - MapCache](https://qiita.com/softark/items/0279178a484b451b15a5)

今回からは、デモ・アプリとしての要素がたくさん残っている QWC2 に戻って、アプリの外観や機能をカスタマイズしていきます。

マニュアルとして、`QWC2 / QWC Services` のドキュメントを参照します。

- [QWC2 / QWC Services](https://qwc-services.github.io/master/) > 
    - [QWC2 Viewer Configuration](https://qwc-services.github.io/master/configuration/ViewerConfiguration/)
    - [Plugin reference](https://qwc-services.github.io/master/references/qwc2_plugins/)


## 1. テーマ設定のスリム化

`themesConfig.json` に残っている不要なものをごっそり削除して全体の見通しを良くしておきます。

ただし、あとで参照できるようにバックアップは取っておきます。

### 1-1. 不要なテーマを削除

自作プロジェクト以外のテーマを削除します。

- デモ・データとして付属している "Liegenschaftsprojekte Stadt Uster"
- 同じく "Dev Tests" グループと、その中の "Demo"
- QGIS Server との連携テストに使用した "World"

全部ごっそりと削除。

### 1-2. 参照していない外部レイヤと背景レイヤを削除

自作プロジェクトから参照していない外部レイヤと背景レイヤも全部削除します。

背景レイヤ "mapnik" (Open Street Map) は残しておいても良いかな？

### 1-3. "themesInfoLinks"?

よく分からないので残しておきます。

### 1-4. QGIS Server の設定変更

テーマ "world" を QWC2 から削除したので、QGIS Server の設定からも削除しておきます。

#### 1-4-1-1. "world" 用のソケットとサービスを止める

```bash
sudo systemctl stop qgis-server@world.socket
sudo systemctl disable qgis-server@world.socket
sudo systemctl stop qgis-server@world.service
sudo systemctl disable qgis-server@world.service
sudo systemctl daemon-reload
sudo systemctl reset-failed
```

#### 1-4-1-2. /etc/nginx/conf.d/qgis-server.conf

`/etc/nginx/conf.d/qgis-server.conf` から "world" 用の設定を削除します。

```diff_nginx
    server {
        listen       8082;
        server_name  webgis.mydomain;

        gzip off;
        include fastcgi_params;

        # CORS を許可
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

-       location /world/ {
-           fastcgi_pass unix:/run/qgis-server-world.sock;
-       }
        location /isg/ {
            fastcgi_pass unix:/run/qgis-server-isg.sock;
        }

        error_log /var/log/nginx/qgis-server-error.log;
        access_log /var/log/nginx/qgis-server-access.log;
    }
```

`nginx` を再起動しておきます。

```bash
sudo systemctl restart nginx
```

## 2. アイコン、ロゴ、タイトルの変更

まず、画面の左上の部分が気になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12310/31db632d-9c3b-4660-803f-eb2de52e7063.png)

アイコンやロゴ、そしてページのタイトルが QWC2 のものですので、自分のサイトのものに変更したいですね。

そして "Toggle API demo" の目障りなリンクがあります。クリックして開くと、このような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12310/bcf675be-1856-4024-9b8e-81e393f1d9ea.png)

こんなもん、要らんでしょう。

### 2-1. API demo を削除する

よく読んでみると、次のように書かれています。

> Note: **These examples work with the QWC2 Test 2056 theme**
> You can remove this box by removing api_examples.js from index.html.

API demo は、`2056` テーマが無いと動かないそうです。`index.html` から `api_examples.js` を削除したら、このボックスを削除出来るとのことなので、さっそくそのようにします。

```diff_html
-           <script type="text/javascript" src="api_examples.js"></script>
```

### 2-2. タイトルを変更する

`qwc2-demo-app/index.html` を編集して、ページのタイトルを変更します。

```diff_html
-           <title>QGIS Web Client 2</title>
+           <title>i-GIS</title>
```

### 2-3. アイコンを差し替える

`qwc2-demo-app/static/assets/img` のディレクトリにある以下のファイルを差し替えます。

- `app_icon.png`
- `app_icon_72.png`
- `app_icon_114.png`
- `app_icon_144.png`
- `favicon.ico`

### 2-4. ロゴを差し替える

`qwc2-demo-app/static/assets/img` のディレクトリにある以下のファイルを差し替えます。

- `logo.svg` ... デスクトップ用ロゴ
- `logo-mobile.svg` ... モバイル用ロゴ
- `qwc-logo.svg`

### 2-5. 画像の作成と差し替えについて

#### 2-5-1. 画像の作成

画像の作成は、次の手順によることをお奨めします。

1. 最初に `SVG` を作成
    - `Inkscape` などのベクタ画像編集ツールを使う
    - 横長のもの（`logo.svg`）と正方形のもの（`logo-mobile.svg`, `qwc-logo.svg`）を作成する
        - `logo-mobile.svg` と `qwc-logo.svg` はほぼ同一内容
        - 好みによっては、`logo-svg` も共通の正方形のものにしてよい
2. 次に `SVG` から `PNG` を作成
    - `Inkscape` などで正方形の `SVG` を `PNG` にエクスポートする
        - `app_icon.png` ... 55 x 57
        - `app_icon_72.png` ... 72 x 72
        - `app_icon_114.png` ... 114 x 114
        - `app_icon_144.png` ... 144 x 144
        - `app_icon_large.png` ... 512 x 512 ... `favicon.ico` 作成 用
    - エクスポート時の背景色は透過が良いとは限らない
3. 最後に `PNG` から `favicon.ico` を作成
    - アイコン作成サービス（[favicon.io](https://favicon.io/) がお奨め）を利用して、`PNG` から `favicon.ico` を作成する
        - このために、解像度の高い `app_icon_large.png` を用意する

面倒くさくても `SVG` から作成すれば、変更が必要になったときにも楽に対応できます。

#### 2-5-2. 画像の差し替え

ここでは全て元の画像ファイルを上書きして差し替えています。`fabicon.ico` を例外として、別の名前で画像ファイルを保存して参照しても良い筈です。

`PNG` 形式のアイコン画像ファイルは、`qwc2-demo-app/index.html` を編集して別の名前のものに差し替えることが出来ます。

```diff_html
-           <link rel="apple-touch-icon" href="assets/img/app_icon.png"/>
-           <link rel="apple-touch-icon" sizes="72x72" href="assets/img/app_icon_72.png"/>
-           <link rel="apple-touch-icon" sizes="114x114" href="assets/img/app_icon_114.png"/>
-           <link rel="apple-touch-icon" sizes="144x144" href="assets/img/app_icon_144.png"/>
+           <link rel="apple-touch-icon" href="assets/img/my_app_icon.png"/>
+           <link rel="apple-touch-icon" sizes="72x72" href="assets/img/my_app_icon_72.png"/>
+           <link rel="apple-touch-icon" sizes="114x114" href="assets/img/my_app_icon_114.png"/>
+           <link rel="apple-touch-icon" sizes="144x144" href="assets/img/my_app_icon_144.png"/>
            <link rel="icon" href="assets/img/favicon.ico" />
```

`SVG` ファイルも違う名前のものを参照させることが出来るはずですが、どこで設定するのかよく分かりませんし、デスクトップとモバイルで勝手に `logo.svg` と `logo-mobile-svg` が切り替わっています。`qwc-logo.svg` については、どこで使われるのか、よく分かりませんでした。

という次第ですので、全て、元のファイルを退避させた上で、同じ名前で新しいファイルを登録するのが、簡単で間違いが無くて良いでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12310/d53bd5e0-604e-44cc-82fd-4285c2762fc5.png)

ということで、ページのタイトルを `"i-GIS"`、ロゴを `"i-GIS"` という文字列から作成したロゴに変更しました。アイコンは `"iG"` から作成したものです。

## 3. NewsPopup を出さない

毎回ニュースを表示しようとする `NewsPopup` が鬱陶しいので、出て来ないようにします。

### 3-1. プラグインについて

QWC2 では、ほとんどの機能がプラグインとして実装されています。`NewsPopup` のような小物は当然そうですが、テーマ・スイッチャー、レイヤ・ツリーなどの大物も全部プラグインです。

プラグインの設定は、`qwc2-demo-app/static/config.json` の `"plugins"` のノードの下に、以下のように、`"common"`, `"mobile"`, `"desktop"` に分けて記述されています。

```
config.json
    ...
    + "plugins"
        + "common"
            + "Map"
            + "HomeButton"
            ...
        + "mobile"
            + "BottomBar"
        + desktop"
            + "TaskButton"
            + "TaskButton"
            ...
    ...
```

### 3-2. NewsPopup プラグインを無効化する

`qwc2-demo-app/static/config.json` で、`NewsPopup` プラグインを設定しているところを削除します。

```diff_json
        "plugins": {
            "common": [
                ...
-               {
-                   "name": "NewsPopup",
-                   "cfg": {
-                       "newsDocument": "https://example.com/",
-                       "newsRev": "20230411"
-                   }
-               },
                ...
            ]
            ...
        }
```

これだけで `MenuPopup` は無効になりますが、さらに、`qwc2-demo-app/js/appConfig.js` で `NewsPopup` プラグインをインポートしている個所も削除します。

```diff_javascript
    ...
    import MeasurePlugin from 'qwc2/plugins/Measure';
-   import NewsPopupPlugin from 'qwc2/plugins/NewsPopup';
+   // import NewsPopupPlugin from 'qwc2/plugins/NewsPopup';
    import PortalPlugin from 'qwc2/plugins/Portal';
    ...
        pluginsDef: {
            plugins: {
                ...
                MeasurePlugin: MeasurePlugin,
-               NewsPopupPlugin: NewsPopupPlugin,
+               // NewsPopupPlugin: NewsPopupPlugin,
                PortalPlugin: PortalPlugin,
                ...
            }
```

後の方の作業は、運用版としてデプロイされるファイルが少しでも軽くなるようにと思ってするものですが、余計なお世話かも知れません。QWC2 がコンパイル時に不要なプラグインを除外するように、宜しくやってくれているのかも知れません。未確認です。

余談ですが、`https://example.com` というのが実在するのですね。`IANA` が管理・運営（？）しているんだ。知りませんでした。 

- https://example.com

## 4. ポータルをカスタマイズする

`qwc2-demo-app/static/config.json` を編集して、ポータルをカスタマイズします。

### 4-1. 名称を変更する

まず、トップバーのテキストを "QWC2 Demo Portal" から "ポータル" に変更します。

```diff_json
                {
                    "name": "Portal",
                    "cfg": {
                        "logo": "logo.svg",
-                       "topBarText": "QWC2 Demo Portal",
+                       "topBarText": "ポータル",
                        "showMenuOnStartup": true,
                        "keepMenuOpen": true,
```

### 4-2. 左下の admin ユーザ表示を消す

画面の左下に、ユーザのアイコンと `admin` というユーザ名が表示されています。しかし、スタンドアローンの QWC2 ではユーザ認証は出来ませんので、この表示は不要です。

`qwc2-demo-app/static/config.json` を編集して、`"username"` に空白を設定すれば、アイコンもろとも非表示になります。

```diff_json
        ...
-       "username": "admin",
+       "username": "",
        ...
```

### 4-3. 右下のリンクを変更する

次は、画面右下にクレジットとして小さく表示される二つのリンクです。一つに減らして、メインのサイトへのリンクだけにします。

```diff_json
                        "bottomBarLinks": [
                            {
-                               "href": "http://www.example.com",
-                               "label": "Example.com",
-                               "target": "iframe"
-                           },
-                           {
-                               "href": "http://www.test.com",
-                               "label": "Test.com"
+                               "href": "https://isarigami.net",
+                               "label": "岩座神ネット"
                            }
                        ],
```

### 4-4. メニュー項目のカスタマイズ

#### 4-4-1. ヘルプ

次は、メニューの項目で、最初は "Help" です。この Web 地図アプリの説明書があれば、それへのリンクを設定します。

```diff_json
                        "menuItems": [
                            {
                                "key": "Help",
                                "icon": "info",
-                               "url": "http://example.com"
+                               "url": "https://isarigami.net/site/map/help",
+                               "target": "iframe"
                            },
```

- `"key"` ... 翻訳データのキーを指定します。日本語では、"Help" は "ヘルプ" と翻訳されます
- `"icon"` ... `qwc2-demo-app/qwc2/icons` 以下にある `SVG` ファイルの拡張子抜きのファイル名を指定します
- `"url"` ... ヘルプを提供しているページの `URL`
- `"target"` ... ヘルプを表示する方法
    - `"_blank"` ... 新しいタブを開いて表示（デフォルト値）
    - `"iframe"` ... インライン・フレームで表示

説明書が無い場合は項目をごっそり削除します。

#### 4-4-2. 外部リンク

次は、外部リンクです。これも、リンクしたいページが特に無ければ、項目自体を削除します。

```diff_json
                            {
-                               "key": "ExternalLink",
-                               "icon": "link",
-                               "url": "http://iexample.com?extent=$e$"
+                               "key": "InetMaps",
+                               "icon": "open_link",
+                               "url": "https://isarigami.net/site/map"
                            },
-                           {
-                               "key": "IframeLink",
-                               "icon": "link",
-                               "url": "http://example.com",
-                               "target": "iframe"
-                           },
```

- `"link"` アイコンは `"open_link"` アイコンに変更します

#### 4-4-3. 地図ツール

最後に、"地図ツール" というアイテムと、それをクリックすると展開される二つのサブ・アイテムです。これらも外部リンクになっています。

アイテムの名前を変更して、注目すべきサイトやよくお世話になるサイトへのリンクでも貼っておきましょう。

```diff_json
                            {
-                               "key": "Tools",
-                               "icon": "tools",
+                               "key": "ExternalSites",
+                               "icon": "collapse",
                                "subitems": [
                                    {
-                                       "key": "ExternalLink2",
-                                       "icon": "link",
-                                       "url": "http://example.com?extent=$e$"
+                                       "key": "GsiJp",
+                                       "icon": "open_link",
+                                       "url": "https://www.gsi.go.jp/"
                                    },
                                    {
-                                       "key": "ExternalLink3",
-                                       "icon": "link",
-                                       "url": "http://example.com?extent=$e$"
+                                       "key": "Hyogo50cm",
+                                       "icon": "open_link",
+                                       "url": "https://www.geospatial.jp/ckan/dataset/2022-hyougo-geo-potal"
+                                   },
+                                   {
+                                       "key": "HinataGis",
+                                       "icon": "open_link",
+                                       "url": "https://hgis.pref.miyazaki.lg.jp/hinata/"
                                    }
                                ]
                            }
                        ]
                    }
                }
            ],
```

上記で "key" として指定したアイテム名の多くは、翻訳ファイルに項目が無いもので、このままでは理解できないメニューになってしまいます。

これについて、どうすれば良いか、次に説明します。

### 4-5. 翻訳を追加または修正

メニュー・アイテムの `"key"` の中で、以下のものは QWC2 の翻訳ファイルに登録されていません。

- `"InetMaps"`
- `"ExternalSites"`
- `"GsiJp"`
- `"Hyogo50cm"`
- `"HinataGis"`

これらは、それぞれ、以下のように表示されます。

- `appmenu.items.InetMaps`
- `appmenu.items.ExternalSites`
- `appmenu.items.GsiJp`
- `appmenu.items.Hyogo50cm`
- `appmenu.items.HinataGis`

また、`"Help"` というキーは `"ヘルプ"` と表示されますが、`"操作説明書"` と表示させたいところです。

これらについて、翻訳を追加または修正するためには、次のようにします。

#### 4-5-1. 追加または修正する項目を列挙する

`qwc2-demo-app/static/translations/tsconfig.json` の `"extra_strings"` セクションに追加したいキーを追加します。また、同じく、翻訳を修正したいキーを `"overrides"` セクションに追加します。

```diff_json
        "extra_strings": [
+           "appmenu.items.InetMaps",
+           "appmenu.items.ExternalSites",
+           "appmenu.items.GsiJp",
+           "appmenu.items.Hyogo50cm",
+           "appmenu.items.HinataGis",
            "search.coordinates",
            ...
        ],
        "overrides": [
+           "appmenu.items.Help",
            "bottombar.viewertitle_label"
        ],
```

このようにアプリ固有のカスタマイズ項目を `tsconfig.json` に列挙しておかないと、`yarn start` や `yarn run prod` を実行したときに翻訳ファイルが QWC2 の標準状態まで戻されてしまいます。

#### 4-5-2. 翻訳ファイルの項目を追加または修正する

日本語用の翻訳ファイルは `qwc2-demo-app/static/translations/ja-JP.json` ですので、これを編集します。

```diff_json
    {
        "locale": "ja-JP",
        "messages": {
            "appmenu": {
                "items": {
+                   "ExternalSites": "外部サイト",
+                   "GsiJp": "国土地理院",
+                   "Hyogo50cm": "兵庫県50cmメッシュ",
+                   "HinataGis": "ひなた GIS",
+                   "InetMaps": "岩座神の地図",
-                   "Help": "ヘルプ",
+                   "Help": "操作説明書",
                    "Bookmark": "ブックマーク",
                    ...
```

アプリが日本語以外のユーザに利用される場合を考慮に入れて `qwc2-demo-app/static/translations/en-US.json` も編集して、英語の翻訳を提供するのが良いでしょう。

```diff_json
    {
        "locale": "en-US",
        "messages": {
            "appmenu": {
                "items": {
+                   "ExternalSites": "External Sites",
+                   "GsiJp": "GSI Authority of Japan",
+                   "Hyogo50cm": "50cm Mesh Data of Hyogo Pref.",
+                   "HinataGis": "HINATA GIS - Miyazaki, Japan",
+                   "InetMaps": "Maps of Isarigami",
-                   "Help": "Help",
+                   "Help": "Operation Manual",
                    "Bookmark": "Bookmarks",
                    ...
```

もちろん、その他の言語にも対応するに越したことは無いのですが、翻訳データが欠損している場合は `en-US` がフォールバックとなりますので、最低限、英語には対応しておきたいところです。

### 4-6. 翻訳を諦めて key でなく title を使う

日本語を読めないユーザに対しては不親切になりますが、`"key"` ではなく `"title"` を使ってメニュー項目のタイトルを設定することも出来ます。例えば、

```diff_json
                                    {
-                                       "key": "GsiJp",
+                                       "title": "国土地理院",
                                        "icon": "open_link",
                                        "url": "https://www.gsi.go.jp/"
                                    },
                                    {
-                                       "key": "Hyogo50cm",
+                                       "title": "兵庫県50cmメッシュ",
                                        "icon": "open_link",
                                        "url": "https://www.geospatial.jp/ckan/dataset/2022-hyougo-geo-potal"
                                    },
                                    {
-                                       "key": "HinataGis",
+                                       "title": "ひなた GIS (宮崎県）",
                                        "icon": "open_link",
                                        "url": "https://hgis.pref.miyazaki.lg.jp/hinata/"
                                    }
 ```

この方法の方が圧倒的に手軽ですが、メニュー項目名などの主要な UI 要素は可能な限り翻訳を提供することをお奨めします。

さて、これまでの作業の結果、ポータルは下のスクリーンショットのようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12310/c5007369-5cf3-4c00-bd55-3d1b6a3febca.png)

それなりに形が整ってきた訳ですが、、、

### 4-7. ポータルって必要か？

こうやって見ると、ポータル自体を割愛しても良いかな、という気になります。

フィルタが要るほど沢山のテーマを扱っている訳でもなく、個別のテーマ画面でもテーマの選択は不自由なく出来ますから、ポータルを飛ばしてすぐにテーマを表示する方がユーザ・フレンドリーで良くないか、と。

外部リンクは、有れば嬉しいかも知れないけれど、どうしても必要なものなら、個別のテーマ画面のメニューに入れれば良いでしょう。

#### 4-7-1. ポータルの削除

`Portal` プラグインも `NewsPopup` の場合と同じようにして削除出来ます。

ただし注意が必要なのは、`TopBar` というプラグインがメニュー・アイテムとして `Portal` を参照している事です。この参照も一緒に削除する必要があります。

```diff_json
        "plugins": {
            "common": [
                ...
                {
                    "name": "TopBar",
                    "cfg": {
                        "menuItems": [
-                           {
-                               "key": "Portal",
-                               "icon": "themes"
-                           },
                            {
                                "key": "ThemeSwitcher",
                                "icon": "themes",
                                "shortcut": "alt+shift+t"
                            },
                            ...
```

## 5. サムネール

### 5-1. テーマのサムネール

テーマのサムネール画像は自動的に生成されますが、縦横比のおかしな低品質な画像になります。自分で適当なスクリーンショットを取って、必要な大きさに切り出した画像ファイルを作成し、それをテーマに設定する方が良いでしょう。

以下の手順で作業します。

1. 200 x 100 ピクセルの画像ファイルを作成する
    - ファイル名は `テーマ識別名` + `.png` にすること
2. その画像ファイルを `qwc2-demo-app/static/assets/img/mapthumbs` ディレクトリに置く
3. その画像ファイルをテーマのサムネールとして設定する
    - ファイル名だけを指定

設定は、`qwc2-demo-app/themesConfig.json` で行います。

```diff_json
        "themes": {
            "items": [
                {
                    "id": "isg",
                    ...
+                   "thumbnail": "isg.png"
                }
            ],
            ...
```

これで、ポータルおよびテーマ・スイッチャーで表示されるサムネールを思い通りのものにすることが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12310/ec089a6e-945c-48ba-9f46-e1a154b0b8eb.png)

### 5-2. 背景レイヤのサムネール

背景スイッチャに表示されるサムネールは、手作業で指定しない限り、"Preview Not Available" という文字列を含むデフォルト画像になります。

これも、自分で適当なスクリーンショットを取って、必要な大きさに切り出した画像ファイルを作成し、それを背景レイヤに設定する方が良いでしょう。

以下の手順で作業します。

1. 150 x 75 ピクセルの画像ファイルを作成する
    - ファイル名は `背景レイヤ識別名` + `.png` にすること
2. その画像ファイルを `qwc2-demo-app/static/assets/img/mapthumbs` ディレクトリに置く
3. その画像ファイルを背景レイヤのサムネールとして設定する
    - ファイル名だけを指定

設定は、`qwc2-demo-app/themesConfig.json` で行います。

```diff_json
            "backgroundLayers": [
                {
                    "name": "gsijp-std",
                    "type" : "xyz",
                    "title" : "国土地理院-標準地図",
                    "tiled" : true,
-                   "url" : "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png"
+                   "url" : "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
+                   "thumbnail": "gsijp-std.png"
                },
                ...
```

これで背景スイッチャーの使い勝手がかなり良くなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12310/6e66aa76-6801-4014-98b2-349316439990.png)

## 6. テーマ情報リンク

テーマ・スイッチャーに、そのテーマに関する情報の入手先をリンクとして表示させることが出来ます。

### 6-1. テーマ情報リンクの定義

`qwc2-demo-app/themesConfig.json` の `"themes"` ノードの下に `"themeInfoLinks"` ノードを作って、テーマ情報リンクの定義を書きます。サンプルの定義が残っているので、それを修正していきます。

```diff_json
        "themes": {
            "items": [ ... ],
            "groups": [],
            "externalLayers": [ ... ],
            "backgroundLayers": [ ... ],
            "themeInfoLinks": [
                {
-                   "name": "example_link",
-                   "title": "Example link",
-                   "url": "https://example.com",
-                   "target": "mydialogname"
+                   "name": "inet-link",
+                   "title": "岩座神ネット",
+                   "url": "https://isarigami.net",
+                   "target": "iframe"
                },
                {
-                   "name": "example_link2",
-                   "title": "Example link 2",
-                   "url": "https://example.com/",
-                   "target": "_blank"
+                   "name": "inet-map-link",
+                   "title": "岩座神の地図",
+                   "url": "https://isarigami.net/site/map",
+                   "target": "iframe"
                }
            ]
        },
```

- `"name"` ... テーマ情報リンクの識別名
- `"title"` ... メニュー・アイテムとして表示されるテーマ情報リンクの表示名
- `"url"` ... テーマ情報のリンク先
- `"target"` ... 表示方法
    - 何も指定しなければ現在のウィンドウでリンクが開かれます（そんなデフォルトあるか？）
    - サンプルの `"mydialogname"` は、カスタマイズされたポップアップ・ダイアログを指定するものだと想像しますが、よく分かりません
    - `"iframe"` の指定は無視されて `"_blank"` と同じ動作になります。これもよく分かりません
    - とりあえず `"_blank"` を指定するのが無難でしょう

### 6-2. テーマ情報リンクをテーマで参照する

`qwc2-demo-app/themesConfig.json` の `"themes"/"iems" ノードの下のテーマのノードに `"themeInfoLinks"` ノードを作って、上記のテーマ情報リンク定義への参照を設定します。

```diff_json
        "themes": {
            "items": [
                {
                    "id": "isg",
                    "url": "http://gis-svr.vmware:8082/isg",
                    ...
+                   "themeInfoLinks": {
+                       "title": "テーマの情報",
+                       "entries": [
+                           "inet-link",
+                           "inet-map-link"
+                       ]
+                   }
                }
            ],
```

- `"title"` ... ドロップダウン・メニューに表示されるタイトル
- `"entries"` ... ドロップダウン・メニューのエントリー
    - テーマ情報リンクの識別名を列挙する

#### 6-2-1. タイトルを翻訳対象とする

`"title"` の代りに `"titleMsgId"` でタイトルを指定して、その内容を翻訳ファイルで定義することも出来ます。

```diff_json
                    "themeInfoLinks": {
-                       "title": "このテーマについて ...",
+                       "titleMsgId": "ThemeInfo",
                        "entries": [
                            "inet-link",
                            "inet-map-link"
                        ]
                    }
```

`"ThemeInfo"` は、`qwc2-demo-app/static/translations` ディレクトリの下にある`tsconfig.json` および `ja-JP.json`, `en-US.json` などで、最上位レベルのノードのメッセージとして追加します。

`qwc2-demo-app/static/translations/tsconfig.json`
```diff_json
    "extra_strings": [
+       "ThemeInfo",
        "appmenu.items.ExternalSites",
        "appmenu.items.GsiJp",
        ...
    ],
```

`qwc2-demo-app/static/translations/ja-JP.json`
```diff_json
    {
        "locale": "ja-JP",
        "messages": {
+           "ThemeInfo": "このテーマについて ...",
            "appmenu": {
                "items": {
                    "ExternalSites": "外部サイト",
                    "GsiJp": "国土地理院",
                    ...
```

### 6-3. テーマ情報リンクの表示例

テーマのタイトルの下に、テーマ情報リンクのドロップダウン・メニューが追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12310/b2a8c20d-611a-4769-b238-ce65cf005032.png)

メニューをドロップダウンすると、次のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12310/f7824737-7c54-43c0-8176-b5531bd963e3.png)

テーマ別画面のテーマ・スイッチャーでも、各テーマのタイトルとサムネールの間にテーマ情報リンクのドロップダウン・メニューが表示されます。

## And so, what's next?

これでポータルに関係するカスタマイズは一通り完了です。

個別のテーマ画面には手を着けていない状態ですが、今回の作業で、ある程度は、今後のカスタマイズ作業に役立つノウハウも身につきました。

次回は、テーマ別の画面、すなわちマップ・ビューワに移動して、カスタマイズを続けていきます。

- [QGIS データを Web で表示 #8 - QWC2（続々々）](https://qiita.com/softark/items/cf7c4262b7377927ec1b)