Drupalで管理者以外のユーザーにも設定画面へのアクセスを許可する方法

本記事の一部はAIが作成しました。 概要 Drupalでカスタムモジュールの設定画面を作成する際、管理者以外のユーザーにもアクセスを許可したい場合があります。今回は、GitHub Webhookモジュールを例に、この問題の解決方法を説明します。 問題の発生 最初の状態では、以下のようなルーティング設定でした: # github_webhook.routing.yml github_webhook.settings: path: '/admin/config/github_webhook' defaults: _form: '\Drupal\github_webhook\Form\SettingsForm' _title: 'GitHub Webhook Settings' requirements: _permission: 'administer site configuration' この設定では、administer site configuration権限を持つ管理者のみがアクセス可能で、一般ユーザーはアクセスできませんでした。 解決方法1: 専用権限の作成 まず、専用の権限を作成します。github_webhook.permissions.ymlファイルを新規作成: access github webhook settings: title: 'Access GitHub Webhook Settings' description: 'Allow users to access GitHub webhook configuration.' そして、ルーティングファイルを更新: # github_webhook.routing.yml github_webhook.settings: path: '/admin/config/github_webhook' defaults: _form: '\Drupal\github_webhook\Form\SettingsForm' _title: 'GitHub Webhook Settings' requirements: _permission: 'access github webhook settings' 問題の発覚: /adminパスの制限 しかし、この変更だけでは解決しませんでした。Drupalでは/admin配下のパスは管理エリアとして扱われ、追加の権限チェックが行われるためです。 ...

2025年5月28日 · 1 分 · Nakamura

NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成

お知らせ 本記事で紹介する流れをわかりやすくした記事を作成しました。以下も参考にしてください。 概要 NDL古典籍OCR-Liteを用いたアノテーション付きIIIFマニフェストファイルとTEI/XMLファイルの作成を行うツールを試作したので紹介します。 アノテーション付きIIIFマニフェストファイルの作成 まず、NDL古典籍OCR-Liteを用いて、IIIFマニフェストファイルを入力として、アノテーション付きIIIFマニフェストファイルを出力するGradioアプリを作成しました。Hugging FaceのSpaceを用いて公開しています。 https://nakamura196-ndlkotenocr-lite-iiif.hf.space/ 出力結果として、以下のようなアノテーション付きIIIFマニフェストファイルが得られます。 { "@context": "http://iiif.io/api/presentation/3/context.json", "id": "https://dl.ndl.go.jp/api/iiif/3437686/manifest.json", "type": "Manifest", "label": { "none": [ "校異源氏物語. 巻一" ] }, "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1", "type": "Canvas", "width": 6890, "height": 4706, "label": { "none": [ "1" ] }, "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/page", "type": "AnnotationPage", "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/page/imageanno", "type": "Annotation", "motivation": "sc:painting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1", "body": { "id": "https://dl.ndl.go.jp/api/iiif/3437686/R0000001/full/full/0/default.jpg", "type": "Image", "format": "image/jpeg", "width": 6890, "height": 4706, "service": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/R0000001", "type": "ImageService2", "profile": "level2" } ] } } ] } ], "annotations": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos", "type": "AnnotationPage", "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/0", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=5270,275,114,935", "body": { "type": "TextualBody", "value": "一・〇・・・・・・一一一一・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/1", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=5293,2009,218,424", "body": { "type": "TextualBody", "value": "○〇" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/2", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=5092,3272,63,80", "body": { "type": "TextualBody", "value": "一一" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/3", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=4375,304,103,1475", "body": { "type": "TextualBody", "value": "ス〇〇〇六〇〇〇一〇〇〇〇〇〇〇一一一〇〇〇一一一一〇〇〇〇〇〇〇〇〇〇一一・〇〇・・・・・・・の〇〇・・・・一・・・" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/4", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=4375,2853,45,522", "body": { "type": "TextualBody", "value": "□琉球□□□□□□□□□□□□□□□□□" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/5", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=4283,2756,63,252", "body": { "type": "TextualBody", "value": "〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇一〇〇一〇〇〇" } }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1/annos/6", "type": "Annotation", "motivation": "commenting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/1#xywh=694,499,310,2991", "body": { "type": "TextualBody", "value": "同校異源氏物巻一" } } ] } ] }, { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2", "type": "Canvas", "width": 6890, "height": 4706, "label": { "none": [ "2" ] }, "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2/page", "type": "AnnotationPage", "items": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2/page/imageanno", "type": "Annotation", "motivation": "sc:painting", "target": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2", "body": { "id": "https://dl.ndl.go.jp/api/iiif/3437686/R0000002/full/full/0/default.jpg", "type": "Image", "format": "image/jpeg", "width": 6890, "height": 4706, "service": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/R0000002", "type": "ImageService2", "profile": "level2" } ] } } ] } ], "annotations": [ { "id": "https://dl.ndl.go.jp/api/iiif/3437686/canvas/2/annos", "type": "AnnotationPage", "items": [] } ] } ] } TEI/XMLファイルの作成 上記で得られたアノテーション付きIIIFマニフェストファイルを入力として、TEI/XMLファイルを作成するライブラリを作成しました。 ...

2025年5月27日 · 4 分 · Nakamura

IIIFマニフェストファイルから画像URLの一覧を含むCSVファイルを作成する

概要 IIIFマニフェストファイルから画像URLの一覧を含むCSVファイルを作成するアプリを作成したので備忘録です。 以下からアクセスいただけます。 https://iiif-demo-next.vercel.app/csv-converter 使い方 国立国会図書館所蔵の「校異源氏物語. 巻一」を対象とします。 https://dl.ndl.go.jp/api/iiif/3437686/manifest.json 以下のフォームにマニフェストファイルのURLを入力し、「CSVをダウンロード」ボタンを押します。 結果、以下のように、URLやサイズの情報を含むCSVファイルがダウンロードされます。 url,width,height,canvas https://dl.ndl.go.jp/api/iiif/3437686/R0000001/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/1 https://dl.ndl.go.jp/api/iiif/3437686/R0000002/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/2 https://dl.ndl.go.jp/api/iiif/3437686/R0000003/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/3 https://dl.ndl.go.jp/api/iiif/3437686/R0000004/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/4 https://dl.ndl.go.jp/api/iiif/3437686/R0000005/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/5 https://dl.ndl.go.jp/api/iiif/3437686/R0000006/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/6 https://dl.ndl.go.jp/api/iiif/3437686/R0000007/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/7 https://dl.ndl.go.jp/api/iiif/3437686/R0000008/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/8 https://dl.ndl.go.jp/api/iiif/3437686/R0000009/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/9 https://dl.ndl.go.jp/api/iiif/3437686/R0000010/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/10 https://dl.ndl.go.jp/api/iiif/3437686/R0000011/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/11 https://dl.ndl.go.jp/api/iiif/3437686/R0000012/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/12 https://dl.ndl.go.jp/api/iiif/3437686/R0000013/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/13 https://dl.ndl.go.jp/api/iiif/3437686/R0000014/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/14 https://dl.ndl.go.jp/api/iiif/3437686/R0000015/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/15 https://dl.ndl.go.jp/api/iiif/3437686/R0000016/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/16 https://dl.ndl.go.jp/api/iiif/3437686/R0000017/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/17 https://dl.ndl.go.jp/api/iiif/3437686/R0000018/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/18 https://dl.ndl.go.jp/api/iiif/3437686/R0000019/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/19 https://dl.ndl.go.jp/api/iiif/3437686/R0000020/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/20 https://dl.ndl.go.jp/api/iiif/3437686/R0000021/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/21 https://dl.ndl.go.jp/api/iiif/3437686/R0000022/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/22 https://dl.ndl.go.jp/api/iiif/3437686/R0000023/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/23 https://dl.ndl.go.jp/api/iiif/3437686/R0000024/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/24 https://dl.ndl.go.jp/api/iiif/3437686/R0000025/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/25 https://dl.ndl.go.jp/api/iiif/3437686/R0000026/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/26 https://dl.ndl.go.jp/api/iiif/3437686/R0000027/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/27 https://dl.ndl.go.jp/api/iiif/3437686/R0000028/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/28 https://dl.ndl.go.jp/api/iiif/3437686/R0000029/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/29 https://dl.ndl.go.jp/api/iiif/3437686/R0000030/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/30 https://dl.ndl.go.jp/api/iiif/3437686/R0000031/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/31 https://dl.ndl.go.jp/api/iiif/3437686/R0000032/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/32 https://dl.ndl.go.jp/api/iiif/3437686/R0000033/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/33 https://dl.ndl.go.jp/api/iiif/3437686/R0000034/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/34 https://dl.ndl.go.jp/api/iiif/3437686/R0000035/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/35 https://dl.ndl.go.jp/api/iiif/3437686/R0000036/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/36 https://dl.ndl.go.jp/api/iiif/3437686/R0000037/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/37 https://dl.ndl.go.jp/api/iiif/3437686/R0000038/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/38 https://dl.ndl.go.jp/api/iiif/3437686/R0000039/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/39 https://dl.ndl.go.jp/api/iiif/3437686/R0000040/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/40 https://dl.ndl.go.jp/api/iiif/3437686/R0000041/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/41 https://dl.ndl.go.jp/api/iiif/3437686/R0000042/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/42 https://dl.ndl.go.jp/api/iiif/3437686/R0000043/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/43 https://dl.ndl.go.jp/api/iiif/3437686/R0000044/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/44 https://dl.ndl.go.jp/api/iiif/3437686/R0000045/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/45 https://dl.ndl.go.jp/api/iiif/3437686/R0000046/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/46 https://dl.ndl.go.jp/api/iiif/3437686/R0000047/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/47 https://dl.ndl.go.jp/api/iiif/3437686/R0000048/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/48 https://dl.ndl.go.jp/api/iiif/3437686/R0000049/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/49 https://dl.ndl.go.jp/api/iiif/3437686/R0000050/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/50 https://dl.ndl.go.jp/api/iiif/3437686/R0000051/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/51 https://dl.ndl.go.jp/api/iiif/3437686/R0000052/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/52 https://dl.ndl.go.jp/api/iiif/3437686/R0000053/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/53 https://dl.ndl.go.jp/api/iiif/3437686/R0000054/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/54 https://dl.ndl.go.jp/api/iiif/3437686/R0000055/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/55 https://dl.ndl.go.jp/api/iiif/3437686/R0000056/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/56 https://dl.ndl.go.jp/api/iiif/3437686/R0000057/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/57 https://dl.ndl.go.jp/api/iiif/3437686/R0000058/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/58 https://dl.ndl.go.jp/api/iiif/3437686/R0000059/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/59 https://dl.ndl.go.jp/api/iiif/3437686/R0000060/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/60 https://dl.ndl.go.jp/api/iiif/3437686/R0000061/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/61 https://dl.ndl.go.jp/api/iiif/3437686/R0000062/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/62 https://dl.ndl.go.jp/api/iiif/3437686/R0000063/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/63 https://dl.ndl.go.jp/api/iiif/3437686/R0000064/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/64 https://dl.ndl.go.jp/api/iiif/3437686/R0000065/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/65 https://dl.ndl.go.jp/api/iiif/3437686/R0000066/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/66 https://dl.ndl.go.jp/api/iiif/3437686/R0000067/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/67 https://dl.ndl.go.jp/api/iiif/3437686/R0000068/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/68 https://dl.ndl.go.jp/api/iiif/3437686/R0000069/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/69 https://dl.ndl.go.jp/api/iiif/3437686/R0000070/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/70 https://dl.ndl.go.jp/api/iiif/3437686/R0000071/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/71 https://dl.ndl.go.jp/api/iiif/3437686/R0000072/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/72 https://dl.ndl.go.jp/api/iiif/3437686/R0000073/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/73 https://dl.ndl.go.jp/api/iiif/3437686/R0000074/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/74 https://dl.ndl.go.jp/api/iiif/3437686/R0000075/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/75 https://dl.ndl.go.jp/api/iiif/3437686/R0000076/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/76 https://dl.ndl.go.jp/api/iiif/3437686/R0000077/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/77 https://dl.ndl.go.jp/api/iiif/3437686/R0000078/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/78 https://dl.ndl.go.jp/api/iiif/3437686/R0000079/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/79 https://dl.ndl.go.jp/api/iiif/3437686/R0000080/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/80 https://dl.ndl.go.jp/api/iiif/3437686/R0000081/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/81 https://dl.ndl.go.jp/api/iiif/3437686/R0000082/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/82 https://dl.ndl.go.jp/api/iiif/3437686/R0000083/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/83 https://dl.ndl.go.jp/api/iiif/3437686/R0000084/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/84 https://dl.ndl.go.jp/api/iiif/3437686/R0000085/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/85 https://dl.ndl.go.jp/api/iiif/3437686/R0000086/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/86 https://dl.ndl.go.jp/api/iiif/3437686/R0000087/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/87 https://dl.ndl.go.jp/api/iiif/3437686/R0000088/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/88 https://dl.ndl.go.jp/api/iiif/3437686/R0000089/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/89 https://dl.ndl.go.jp/api/iiif/3437686/R0000090/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/90 https://dl.ndl.go.jp/api/iiif/3437686/R0000091/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/91 https://dl.ndl.go.jp/api/iiif/3437686/R0000092/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/92 https://dl.ndl.go.jp/api/iiif/3437686/R0000093/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/93 https://dl.ndl.go.jp/api/iiif/3437686/R0000094/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/94 https://dl.ndl.go.jp/api/iiif/3437686/R0000095/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/95 https://dl.ndl.go.jp/api/iiif/3437686/R0000096/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/96 https://dl.ndl.go.jp/api/iiif/3437686/R0000097/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/97 https://dl.ndl.go.jp/api/iiif/3437686/R0000098/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/98 https://dl.ndl.go.jp/api/iiif/3437686/R0000099/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/99 https://dl.ndl.go.jp/api/iiif/3437686/R0000100/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/100 https://dl.ndl.go.jp/api/iiif/3437686/R0000101/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/101 https://dl.ndl.go.jp/api/iiif/3437686/R0000102/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/102 https://dl.ndl.go.jp/api/iiif/3437686/R0000103/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/103 https://dl.ndl.go.jp/api/iiif/3437686/R0000104/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/104 https://dl.ndl.go.jp/api/iiif/3437686/R0000105/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/105 https://dl.ndl.go.jp/api/iiif/3437686/R0000106/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/106 https://dl.ndl.go.jp/api/iiif/3437686/R0000107/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/107 https://dl.ndl.go.jp/api/iiif/3437686/R0000108/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/108 https://dl.ndl.go.jp/api/iiif/3437686/R0000109/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/109 https://dl.ndl.go.jp/api/iiif/3437686/R0000110/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/110 https://dl.ndl.go.jp/api/iiif/3437686/R0000111/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/111 https://dl.ndl.go.jp/api/iiif/3437686/R0000112/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/112 https://dl.ndl.go.jp/api/iiif/3437686/R0000113/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/113 https://dl.ndl.go.jp/api/iiif/3437686/R0000114/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/114 https://dl.ndl.go.jp/api/iiif/3437686/R0000115/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/115 https://dl.ndl.go.jp/api/iiif/3437686/R0000116/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/116 https://dl.ndl.go.jp/api/iiif/3437686/R0000117/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/117 https://dl.ndl.go.jp/api/iiif/3437686/R0000118/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/118 https://dl.ndl.go.jp/api/iiif/3437686/R0000119/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/119 https://dl.ndl.go.jp/api/iiif/3437686/R0000120/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/120 https://dl.ndl.go.jp/api/iiif/3437686/R0000121/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/121 https://dl.ndl.go.jp/api/iiif/3437686/R0000122/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/122 https://dl.ndl.go.jp/api/iiif/3437686/R0000123/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/123 https://dl.ndl.go.jp/api/iiif/3437686/R0000124/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/124 https://dl.ndl.go.jp/api/iiif/3437686/R0000125/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/125 https://dl.ndl.go.jp/api/iiif/3437686/R0000126/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/126 https://dl.ndl.go.jp/api/iiif/3437686/R0000127/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/127 https://dl.ndl.go.jp/api/iiif/3437686/R0000128/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/128 https://dl.ndl.go.jp/api/iiif/3437686/R0000129/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/129 https://dl.ndl.go.jp/api/iiif/3437686/R0000130/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/130 https://dl.ndl.go.jp/api/iiif/3437686/R0000131/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/131 https://dl.ndl.go.jp/api/iiif/3437686/R0000132/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/132 https://dl.ndl.go.jp/api/iiif/3437686/R0000133/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/133 https://dl.ndl.go.jp/api/iiif/3437686/R0000134/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/134 https://dl.ndl.go.jp/api/iiif/3437686/R0000135/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/135 https://dl.ndl.go.jp/api/iiif/3437686/R0000136/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/136 https://dl.ndl.go.jp/api/iiif/3437686/R0000137/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/137 https://dl.ndl.go.jp/api/iiif/3437686/R0000138/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/138 https://dl.ndl.go.jp/api/iiif/3437686/R0000139/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/139 https://dl.ndl.go.jp/api/iiif/3437686/R0000140/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/140 https://dl.ndl.go.jp/api/iiif/3437686/R0000141/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/141 https://dl.ndl.go.jp/api/iiif/3437686/R0000142/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/142 https://dl.ndl.go.jp/api/iiif/3437686/R0000143/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/143 https://dl.ndl.go.jp/api/iiif/3437686/R0000144/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/144 https://dl.ndl.go.jp/api/iiif/3437686/R0000145/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/145 https://dl.ndl.go.jp/api/iiif/3437686/R0000146/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/146 https://dl.ndl.go.jp/api/iiif/3437686/R0000147/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/147 https://dl.ndl.go.jp/api/iiif/3437686/R0000148/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/148 https://dl.ndl.go.jp/api/iiif/3437686/R0000149/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/149 https://dl.ndl.go.jp/api/iiif/3437686/R0000150/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/150 https://dl.ndl.go.jp/api/iiif/3437686/R0000151/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/151 https://dl.ndl.go.jp/api/iiif/3437686/R0000152/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/152 https://dl.ndl.go.jp/api/iiif/3437686/R0000153/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/153 https://dl.ndl.go.jp/api/iiif/3437686/R0000154/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/154 https://dl.ndl.go.jp/api/iiif/3437686/R0000155/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/155 https://dl.ndl.go.jp/api/iiif/3437686/R0000156/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/156 https://dl.ndl.go.jp/api/iiif/3437686/R0000157/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/157 https://dl.ndl.go.jp/api/iiif/3437686/R0000158/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/158 https://dl.ndl.go.jp/api/iiif/3437686/R0000159/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/159 https://dl.ndl.go.jp/api/iiif/3437686/R0000160/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/160 https://dl.ndl.go.jp/api/iiif/3437686/R0000161/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/161 https://dl.ndl.go.jp/api/iiif/3437686/R0000162/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/162 https://dl.ndl.go.jp/api/iiif/3437686/R0000163/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/163 https://dl.ndl.go.jp/api/iiif/3437686/R0000164/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/164 https://dl.ndl.go.jp/api/iiif/3437686/R0000165/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/165 https://dl.ndl.go.jp/api/iiif/3437686/R0000166/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/166 https://dl.ndl.go.jp/api/iiif/3437686/R0000167/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/167 https://dl.ndl.go.jp/api/iiif/3437686/R0000168/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/168 https://dl.ndl.go.jp/api/iiif/3437686/R0000169/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/169 https://dl.ndl.go.jp/api/iiif/3437686/R0000170/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/170 https://dl.ndl.go.jp/api/iiif/3437686/R0000171/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/171 https://dl.ndl.go.jp/api/iiif/3437686/R0000172/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/172 https://dl.ndl.go.jp/api/iiif/3437686/R0000173/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/173 https://dl.ndl.go.jp/api/iiif/3437686/R0000174/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/174 https://dl.ndl.go.jp/api/iiif/3437686/R0000175/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/175 https://dl.ndl.go.jp/api/iiif/3437686/R0000176/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/176 https://dl.ndl.go.jp/api/iiif/3437686/R0000177/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/177 https://dl.ndl.go.jp/api/iiif/3437686/R0000178/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/178 https://dl.ndl.go.jp/api/iiif/3437686/R0000179/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/179 https://dl.ndl.go.jp/api/iiif/3437686/R0000180/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/180 https://dl.ndl.go.jp/api/iiif/3437686/R0000181/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/181 https://dl.ndl.go.jp/api/iiif/3437686/R0000182/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/182 https://dl.ndl.go.jp/api/iiif/3437686/R0000183/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/183 https://dl.ndl.go.jp/api/iiif/3437686/R0000184/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/184 https://dl.ndl.go.jp/api/iiif/3437686/R0000185/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/185 https://dl.ndl.go.jp/api/iiif/3437686/R0000186/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/186 https://dl.ndl.go.jp/api/iiif/3437686/R0000187/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/187 https://dl.ndl.go.jp/api/iiif/3437686/R0000188/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/188 https://dl.ndl.go.jp/api/iiif/3437686/R0000189/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/189 https://dl.ndl.go.jp/api/iiif/3437686/R0000190/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/190 https://dl.ndl.go.jp/api/iiif/3437686/R0000191/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/191 https://dl.ndl.go.jp/api/iiif/3437686/R0000192/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/192 https://dl.ndl.go.jp/api/iiif/3437686/R0000193/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/193 https://dl.ndl.go.jp/api/iiif/3437686/R0000194/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/194 https://dl.ndl.go.jp/api/iiif/3437686/R0000195/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/195 https://dl.ndl.go.jp/api/iiif/3437686/R0000196/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/196 https://dl.ndl.go.jp/api/iiif/3437686/R0000197/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/197 https://dl.ndl.go.jp/api/iiif/3437686/R0000198/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/198 https://dl.ndl.go.jp/api/iiif/3437686/R0000199/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/199 https://dl.ndl.go.jp/api/iiif/3437686/R0000200/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/200 https://dl.ndl.go.jp/api/iiif/3437686/R0000201/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/201 https://dl.ndl.go.jp/api/iiif/3437686/R0000202/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/202 https://dl.ndl.go.jp/api/iiif/3437686/R0000203/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/203 https://dl.ndl.go.jp/api/iiif/3437686/R0000204/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/204 https://dl.ndl.go.jp/api/iiif/3437686/R0000205/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/205 https://dl.ndl.go.jp/api/iiif/3437686/R0000206/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/206 https://dl.ndl.go.jp/api/iiif/3437686/R0000207/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/207 https://dl.ndl.go.jp/api/iiif/3437686/R0000208/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/208 https://dl.ndl.go.jp/api/iiif/3437686/R0000209/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/209 https://dl.ndl.go.jp/api/iiif/3437686/R0000210/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/210 https://dl.ndl.go.jp/api/iiif/3437686/R0000211/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/211 https://dl.ndl.go.jp/api/iiif/3437686/R0000212/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/212 https://dl.ndl.go.jp/api/iiif/3437686/R0000213/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/213 https://dl.ndl.go.jp/api/iiif/3437686/R0000214/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/214 https://dl.ndl.go.jp/api/iiif/3437686/R0000215/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/215 https://dl.ndl.go.jp/api/iiif/3437686/R0000216/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/216 https://dl.ndl.go.jp/api/iiif/3437686/R0000217/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/217 https://dl.ndl.go.jp/api/iiif/3437686/R0000218/info.json,6890,4706,https://dl.ndl.go.jp/api/iiif/3437686/canvas/218 メモ 以下の記事で、@iiif/parserというnpmモジュールを紹介しました。 ...

2025年5月27日 · 2 分 · Nakamura

DrupalでJSON形式のFieldを扱うための「JSON Field」モジュールを使用する

概要 DrupalでJSON形式のFieldを扱うための「JSON Field」モジュールを使用する機会がありましたので、備忘録です。 https://www.drupal.org/project/json_field 結果、以下のようにエディタと共にJSONを扱えるようになりました。 インストール 以下により、ダウンロードします。 composer require 'drupal/json_field:^1.4' drush en json_field さらに、以下により、ウィジェットも有効します。 drush en json_field_widget GUIから有効にする場合には、以下の2つを有効にします。 設定 コンテンツタイプのフィールドの管理において、JSONフィールドを追加します。 そして、「フォームの表示管理」において、ウィジェットを選択します。 結果、コンテンツの編集画面で、以下のようなフォームが表示されます。 まとめ DrupalでJSONを管理するにあたり、参考になりましたら幸いです。

2025年5月25日 · 1 分 · Nakamura

TEI/XMLファイルをS3互換のオブジェクトストレージでホストする

概要 TEI/XMLファイルをS3互換のオブジェクトストレージでホストする機会がありましたので、備忘録です。具体的には、mdx Iのオブジェクトストレージを対象にします。 https://mdx.jp/mdx1/p/about/system 背景 TEI/XMLファイルを読み込み、その内容を可視化するウェブアプリケーション(Next.js)を構築します。この時、ファイル数やサイズが小さい場合は、publicフォルダに格納していましたが、これらが大きくなった場合、別の場所でホストすることを考えました。 場所の選択肢は多々ありますが、今回はS3互換であるmdx Iのオブジェクトストレージを対象にします。 GUIを用いたオブジェクトストレージへのファイルアップロード オブジェクトストレージへTEI/XMLファイルをGUI経由でアップロードする方法も多々あります。その中で、これまではCyberduckを使用する方法や、GakunNin RDMを使用する方法などを紹介しました。 一方、今回の事例では、TEI/XML以外のコンテンツをDrupalで管理していました。そこで、Drupalとオブジェクトストレージを接続し、ユーザはDrupalの操作で完結できるようにしました。 Drupalとオブジェクトストレージの接続 以下のモジュールを使用します。 https://www.drupal.org/project/s3fs インストール後、環境設定のページ/admin/configから、S3 File Systemを選択します。 そして、アクセスキーや秘密鍵を登録し、さらにS3のバケット名を登録します。 またAdvanced Configuration OptionsのCustom Host Settingsにおいて、https://s3ds.mdx.jpを入力します。 これでオブジェクトストレージとの接続設定は完了です。 その後、各コンテンツタイプのフィード設定において、アップロード先として「S3 File System」を選択します。 また、今回はTEI/XMLファイルがアップロード対象となるため、「許可されている拡張子」として、xmlを入力します。 この結果、DrupalのGUIを介してアップロードしたTEI/XMLファイルが、mdx Iのオブジェクトストレージに格納されるようになりました。 (参考)DrupalのJSON:APIを用いたファイルの一括アップロード TEI/XMLの初期登録にあたり、Pythonを用いた一括登録を行いました。JSON:APIを用いたファイルの一括アップロードの方法は、以下の記事などが参考になりました。 https://www.drupal.org/node/3024331 一例ですが、以下のようなスクリプトで実現できました。 import requests import json import os from dotenv import load_dotenv from glob import glob from tqdm import tqdm class ApiClient: def __init__(self): load_dotenv(override=True) # DrupalサイトのURL(例) self.DRUPAL_BASE_URL = os.getenv("DRUPAL_BASE_URL") # エンドポイント(JSON:API) # self.JSONAPI_ENDPOINT = f"{self.DRUPAL_BASE_URL}/jsonapi/node/article" # 認証情報(Basic認証) self.USERNAME = os.getenv("DRUPAL_USERNAME") self.PASSWORD = os.getenv("DRUPAL_PASSWORD") def login(self): # ログインリクエスト login_url = f"{self.DRUPAL_BASE_URL}/user/login?_format=json" login_response = requests.post( login_url, json={"name": self.USERNAME, "pass": self.PASSWORD}, headers={"Content-Type": "application/json"} ) if login_response.status_code == 200: self.session_cookies = login_response.cookies def get_csrf_token(self): # CSRFトークンを取得 csrf_token_response = requests.get( f"{self.DRUPAL_BASE_URL}/session/token", cookies=self.session_cookies # ここでログインセッションを渡す ) if csrf_token_response.status_code == 200: # return csrf_token_response.text # self.csrf_token = csrf_token_response.text self.headers = { "Content-Type": "application/vnd.api+json", "Accept": "application/vnd.api+json", "X-CSRF-Token": csrf_token_response.text, } else: # raise Exception(f"CSRFトークン取得失敗: {csrf_token_response.status_code} {csrf_token_response.text}") self.csrf_token = None def upload_file(self, type, uuid, field, file_path, verbose=False): url = f"{self.DRUPAL_BASE_URL}/jsonapi/node/{type}/{uuid}/{field}" # ファイル名を取得 filename = os.path.basename(file_path) # ファイルをバイナリモードで読み込む with open(file_path, 'rb') as f: file_data = f.read() headers = self.headers.copy() headers['Content-Type'] = 'application/octet-stream' headers['Content-Disposition'] = f'attachment; filename="{filename}"' # ファイルをアップロード response = requests.post(url, headers=headers, cookies=self.session_cookies, data=file_data) if response.status_code == 200: if verbose: print(f"ファイルアップロード成功: {filename}") else: print(f"ファイルアップロード失敗: {response.status_code} {response.text}") すでに対象コンテンツが作成済みで、例えばfield_fileといったフィールドにファイルをアップロードする目的で使用することができます。 ...

2025年5月24日 · 2 分 · Nakamura

校異源氏物語テキストDBのDTS(Distributed Text Services) APIの更新

概要 校異源氏物語テキストDBのDTS(Distributed Text Services) APIを更新したので、備忘録です。 背景 DTS(Distributed Text Services) APIは以下で説明されています。 https://distributed-text-services.github.io/specifications/ 以下の記事で、DTS APIの作成について紹介しました。 一方、以下を課題としていました。 今回開発したDTS APIも上記のガイドラインに非対応の箇所がある可能性がある点にご注意ください。 そこで、前回作成したAPIをv1とし、今回はdtsVersionの1-alphaに従ったv2のAPIを作成します。 API 以下がEntry Endpointです。v1とv2の違いは以下です。 v1 https://dts-typescript.vercel.app/api/v1/dts { "navigation": "/api/v1/dts/navigation", "@id": "/api/v1/dts", "@type": "EntryPoint", "collections": "/api/v1/dts/collections", "@context": "dts/EntryPoint.jsonld", "documents": "/api/v1/dts/document" } v2 https://dts-typescript.vercel.app/api/v2/dts { "@context": "https://distributed-text-services.github.io/specifications/context/1-alpha1.json", "dtsVersion": "1-alpha", "@id": "/api/v2/dts", "@type": "EntryPoint", "collection": "/api/v2/dts/collection{?id}", "navigation": "/api/v2/dts/navigation{?resource,ref,down}", "document": "/api/v2/dts/document{?resource,ref}" } 同様に、各種Endpointの記述を変更しています。 ビューアの改修 以下の記事で、DTSのビューア開発について紹介しました。 そして、以下を課題としていましたが、この点に対応できるように改修しました。 Navigation Endpointを使用していますが、現時点で複数階層には非対応です。 例えば、Navigation Endpointは以下のように記述します。 https://dts-typescript.vercel.app/api/v2/dts/navigation?resource=urn:kouigenjimonogatari.1&down=1 { "@context": "https://distributed-text-services.github.io/specifications/context/1-alpha1.json", "dtsVersion": "1-alpha", "@type": "Navigation", "@id": "/api/v2/dts/navigation?resource=urn:kouigenjimonogatari.1&down=1", "resource": { "@id": "urn:kouigenjimonogatari.1", "@type": "Resource", "document": "/api/v2/dts/document?resource=urn:kouigenjimonogatari.1{&ref}", "collection": "/api/v2/dts/collection?id=urn:kouigenjimonogatari.1", "navigation": "/api/v2/dts/navigation?resource=urn:kouigenjimonogatari.1{&ref}", "citationTrees": [ { "@type": "CitationTree", "citeStructure": [ { "@type": "CiteStructure", "citeType": "page", "citeStructure": [ { "@type": "CiteStructure", "citeType": "line" } ] } ] } ] }, "member": [ { "identifier": "5", "@type": "CitableUnit", "level": 1, "parent": null, "citeType": "page" }, { "identifier": "6", "@type": "CitableUnit", "level": 1, "parent": null, "citeType": "page" }, { "identifier": "7", "@type": "CitableUnit", "level": 1, "parent": null, "citeType": "page" }, { "identifier": "8", "@type": "CitableUnit", "level": 1, "parent": null, "citeType": "page" }, ... ] } 特に、CitationTreeを使って、階層を記述します。ビューアがこの情報を処理するように修正することで、以下のように、レベルごとのナビゲーションボタンが表示されるようにしました。 ...

2025年5月24日 · 2 分 · Nakamura

Dockerによるディスク圧迫の調査と対処法【Ubuntu 22.04 運用事例】

はじめに 本記事では、Dockerコンテナやイメージによるディスク圧迫が原因でElasticsearchにエラーが発生した事例と、その調査・対処方法について記録します。同様の問題に直面している方の参考になれば幸いです。 🔍 問題の発生 運用中のElasticsearchで以下のエラーが発生しました。 { "error": { "type": "search_phase_execution_exception", "reason": "all shards failed", "phase": "query", ... }, "status": 503 } 初期調査により、インデックスが close 状態になっており、ディスク容量不足が疑われました。 📊 ディスク使用状況の調査 ルートディレクトリの使用量確認 まず、システム全体のディスク使用状況を確認しました。 sudo du -h --max-depth=1 / | sort -hr | head -n 20 実行結果: 60G / 50G /var 4.7G /usr 2.1G /home 1.2G /opt ... /var ディレクトリが50GBと異常に大きいことが判明しました。 /var ディレクトリの詳細調査 sudo du -h --max-depth=1 /var | sort -hr 実行結果: 50G /var 49G /var/lib 342M /var/log 240M /var/cache 128M /var/spool ... /var/lib がほぼ全容量を占めているため、さらに詳細を調査しました。 sudo du -h --max-depth=1 /var/lib | sort -hr 実行結果: ...

2025年5月22日 · 2 分 · Nakamura

IIIF画像に対する多角形アノテーション支援ツールの改修

概要 IIIF画像に対する多角形アノテーション支援ツール「IIIF Annotator」の改修を行いました。具体的には、以下の2点に取り組みました。 Image Server未使用のマニフェストファイルへの対応 アノテーション付きIIIFマニフェストファイルのエクスポート機能 TEI/XMLファイルのエクスポート機能 以下、これらの改修について説明します。 背景 以下の記事で、アノテーション付与ツールを新規に作成した理由等を説明しました。 今回追加した機能は他のツールでも提供されている機能群になりますが、利便性向上のため追加実装しました。 Image Server未使用のマニフェストファイルへの対応 以下の記事で紹介しているように、IIIFマニフェストファイルにおいて、Image API(Image Server)を使用しないオプションを取ることができます。デメリットもありますが、Cantaloupe Image Serverなどのソフトウェアを導入せずに使用できる点に利点があります。 IIIF Annotatorについて、これまではImage Serverの使用を前提として実装していましたが、今回の改修により、Image Server未使用のマニフェストファイルも読み込めるようにしました。 具体的には以下のように、serviceの有無に応じて、OpenSeadragonに渡すtileSourcesを調整しました。 const tileSources = canvases .map((canvas: Canvas) => { const annotationPage = canvas.items?.[0]; const annotation = annotationPage?.items?.[0]; if (!annotation) return null; const body = annotation.body as { id: string; service?: { "@id": string }[]; }; if (body.service && body.service.length > 0) { return body.service[0]["@id"] + "/info.json"; } else { return { type: "image", url: body.id, }; } }) .filter( (tileSource: string | { type: string; url: string } | null) => tileSource !== null ); エクスポート機能 アノテーション付きIIIFマニフェストファイル、およびTEI/XMLファイルとしてエクスポートする機能を追加しました。エクスポートボタンを押すと、以下のような選択肢が表示されます。 アノテーション付きIIIFマニフェストファイルの用途としては、ダウンロードしたファイルをMirador等に読み込ませることで、アノテーション結果を確認することができます。 またTEI/XMLファイルについては、Oxygen XML Editorの作者モード等を使って、アノテーション結果を確認することができます。 まとめ IIIFのアノテーション結果の活用にあたり、参考になりましたら幸いです。

2025年5月20日 · 1 分 · Nakamura

DTS (Distributed Text Services)のビューア開発

概要 DTS (Distributed Text Services)のビューアを開発したので、備忘録です。 以下のURLからお試しいただけます。 https://dts-viewer.vercel.app/ja/ 背景 DTS (Distributed Text Services)の公式ページは以下です。 https://distributed-text-services.github.io/specifications/ 以下の記事でも取り上げました。 今回、このDTS仕様に一部準拠したビューアを開発しました。 使い方 以下がトップページです。フォームにDTSのURLを入力します。ページ下部で例を提供します。技術的には、Entry pointを使用しています。 コレクションの一覧ページです。Collection Endpointを使用しています。 以下のAPIを例としています。 リンクをたどると、以下のようなリソースの一覧ページに遷移します。 ダウンロードボタンを押すと、TEI/XMLが表示されます。Document Endpointを使用しています。 ナビゲーションボタンを押すと、アクセス可能な部分テキストの一覧が表示されます。Navigation Endpointを使用していますが、現時点で複数階層には非対応です。 リンクをクリックすると、以下のような部分テキストをダウンロードすることができます。 工夫点 公式ページに以下のように記載されています。 The DTS Specification is currently in a public comment period following the 1-alpha release (機械翻訳)DTS仕様は、1-alphaリリースの後、現在パブリックコメント期間中です。 このような背景のため、既存のDTSの記述方法にばらつきがありました。そこで内部でできるだけDTS API (1.0 Draft)に変換し、その結果を可視化するようにしています。 DTS仕様が成熟するにつれ、このような問題は解決されるかと思います。 まとめ DTS仕様は以下のように説明されています。 The Distributed Text Services (DTS) Specification defines an API for working with collections of text as machine-actionable data. ...

2025年5月11日 · 1 分 · Nakamura

Annotorious v2のpolygonツールを使って、polylineを作成する

概要 Annotorious v2のpolygonツールを使って、polylineを作成する方法の備忘録です。 背景 Annotorious v2のウェブサイトは以下です。 https://annotorious.github.io/getting-started/ 以下のように、polygonを記述することができます。 一方、同様の方法でpolylineを記述するツールは、以下のプラグインを含めて、提供されていないようでした。 https://github.com/annotorious/annotorious-v2-selector-pack カスタマイズ 以下のような多角形を作成した場合、 以下のようなJSONファイルが作成されます。 { "type": "Annotation", "body": [ { "type": "TextualBody", "value": "polygon", "purpose": "commenting" } ], "target": { "source": "https://www.e-codices.unifr.ch/loris/gau/gau-Fragment/gau-Fragment_frag001a.jp2/full/full/0/default/jpg", "selector": { "type": "SvgSelector", "value": "<svg><polygon points=\"3383.121337890625,1290.137451171875 945.135498046875,1658.426513671875 885.9696655273438,3003.352294921875 2508.54150390625,3348.424072265625 3485.021484375,2724.35791015625 2170.811767578125,2107.6337890625\" /></svg>" } }, "@context": "http://www.w3.org/ns/anno.jsonld", "id": "#c469b1a3-8902-4443-8f54-47df8bb87d7e" } 上記に対して、autoCloseのような変数を用意し、これがfalseの場合、polygonという文字列をpolylineに変更する処理を加えました。 anno.on("createAnnotation", function (selection: any) { if(!autoClose.value) { selection.target.selector.value = selection.target.selector.value.replace("polygon", "polyline"); } ... }); これにより、以下のように、polygonツールをベースとして、polygonとpolylineを使い分けることができます。 TEI/XMLでの記述 TEI/XMLでの多角形の記述例として、path要素を使用することができます。この場合、polygonであれば始点を終点の後に追加することで、多角形を表現することができます。 <facsimile> <surface ulx="0" uly="0" lrx="8176" lry="6132"> <graphic url="https://www.e-codices.unifr.ch/loris/gau/gau-Fragment/gau-Fragment_frag001a.jp2/full/full/0/default/jpg" /> <zone xml:id="layer_000" change="#ch_layer_000" n="layer_01" type="layer"> <zone xml:id="sign_layer_000_0000" change="#ch_sign_layer_000_0000" type="sign"> <!-- polygon --> <path points="1290.137451171875,3383.121337890625 1658.426513671875,945.135498046875 3003.352294921875,885.9696655273438 3348.424072265625,2508.54150390625 2724.35791015625,3485.021484375 2107.6337890625,2170.811767578125 1290.137451171875,3383.121337890625"></path> </zone> <zone xml:id="sign_layer_000_0001" change="#ch_sign_layer_000_0001" type="sign"> <!-- polyline --> <path points="1393.265625,5290.81005859375 1921.02783203125,3869.745849609375 2982.731689453125,3829.64013671875 3428.122802734375,4874.005859375 2683.244384765625,5741.7509765625 2138.024169921875,4582.19775390625"></path> </zone> </zone> </surface> </facsimile> アプリケーションによっては、始点と終点が一致しなくても閉じた図形を描くことがあるかもしれませんが、polygonとpolylineを使い分ける方法として、参考になりましたら幸いです。 ...

2025年5月5日 · 1 分 · Nakamura

Elasticsearch Search UIでの初期ソート順の指定方法

概要 本記事はAIが作成しました。 ElasticsearchとSearch UIを使って検索インターフェースを構築する際、検索結果のソート順を制御することは一般的な要件です。このガイドでは、Search UI Reactライブラリでソートを設定する方法を説明します。 参考 https://www.elastic.co/docs/reference/search-ui/api-react-search-provider#api-react-search-provider-initial-state 初期状態とソート設定の理解 Search UIライブラリでは、検索の初期状態を指定することができ、ソートの方向とソートするフィールドを含めることができます。これは、ユーザーがページに最初にアクセスしたときに、検索結果が事前に決められた順序で表示されるようにしたい場合に特に役立ちます。 基本的なソート設定の例 Search UI設定でソートを指定する方法は次のとおりです: const config = { // その他の設定オプション... initialState: { sortDirection: 'asc', sortField: 'field_tz_id', }, }; return ( <SearchProvider config={config}> {/* 検索コンポーネント */} </SearchProvider> ); ソート設定オプション initialStateオブジェクトは、ソート関連の2つのプロパティを受け付けます: sortField : ソートしたいElasticsearchインデックス内のフィールド sortDirection : ソートの方向、'asc'(昇順)または'desc'(降順) TypeScriptの型安全性 TypeScriptを使用している場合、ソート方向を定義するときにas constを使用して型安全性を確保できます: const config = { // その他の設定... initialState: { sortDirection: 'asc' as const, // 'asc' | 'desc'として型付け sortField: 'field_tz_id', }, }; これにより、sortDirectionは「asc」または「desc」のみを取り得るようになり、潜在的なエラーを防ぐことができます。 結論 Elasticsearch Search UIで初期ソートを設定する際の参考になりましたら幸いです。

2025年4月30日 · 1 分 · Nakamura

Vercelにデプロイしたexpressについて、vercel.jsonによるcors対応を行う

概要 Vercelにデプロイしたexpressについて、vercel.jsonによるcors対応を行う方法に関する備忘録です。 背景 以下の記事で紹介したプログラムについて、cors対応を行いました。 以下を参考にしています。 https://vercel.com/guides/how-to-enable-cors 方法 対応方法は以下です。他にも方法があるかと思いますが、headersを加えることで対応することができました。 https://github.com/nakamura196/dts-typescript/commit/4c28f66b2af68950656dcb812f3e941d1b9b5feb { "version": 2, "builds": [ { "src": "src/index.ts", "use": "@vercel/node" } ], "rewrites": [ { "source": "/api/dts(.*)", "destination": "/src/index.ts" } ], "redirects": [ { "source": "/", "destination": "/api/dts", "permanent": true } ], "headers": [ { "source": "/api/(.*)", "headers": [ { "key": "Access-Control-Allow-Credentials", "value": "true" }, { "key": "Access-Control-Allow-Origin", "value": "*" }, { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" }, { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" } ] } ] } まとめ 参考になりましたら幸いです。

2025年4月24日 · 1 分 · Nakamura

ArchivematicaのPreservation planningにおいて、Normalizationのルールを追加する

概要 ArchivematicaのPreservation planningにおいて、Normalizationのルールを追加する方法の備忘録です。 背景 拡張子が.jpgである画像をArchivematicaに投入した際、以下のようにFormatがJPEGのものに対してtifファイルを保存用に作成するルールを用意しているにもかかわらず、tifファイルが作成されないことがありました。 そこで、以下のような履歴の画面から、タスクの内容を確認しました。 結果は以下です。 具体的には以下のような記載になっており、該当するルールが存在しない、ということが記載されています。 File format: Image (Raster): Exchangeable Image File Format (Compressed): EXIF Compressed Image 2.2.1 (big-endian) (fmt/645) Not normalizing 11ecf05d-8fc6-4704-a6e9-4a26ef98f186.jpg - No rule or default rule found to normalize for preservation そこで、fmt/645に対するルールを追加します。 ルールの追加 「Create new rule」のリンクをクリックします。 そして、以下のように入力します。 今回は以下を「The related format」として指定します。 Image (Raster): Exchangeable Image File Format (Compressed): EXIF Compressed Image 2.2.1 (big-endian) (fmt/645) 結果、以下のようにルールが新規に追加され、以降、保存用のtifファイルが生成されるようになりました。 まとめ ArchivematicaのPreservation planningにおけるルール追加の一例を紹介しました。参考になりましたら幸いです。 ...

2025年4月24日 · 1 分 · Nakamura

MDX.jpのオブジェクトストレージに対するIPアドレス制限の実装方法

概要 MDX.jpのオブジェクトストレージに対するIPアドレス制限の実装方法を調べました。以下、動作確認を行なった上で、AIが記事を執筆しました。 はじめに 本記事では、MDX.jpが提供するDDN EXAScaler S3互換オブジェクトストレージサービスにおいて、特定のIPアドレスからのみアクセスを許可する設定方法について解説します。 オブジェクトストレージのセキュリティレイヤー DDN EXAScaler S3互換ストレージには、主に以下の3つのセキュリティレイヤーがあります: アクセスキーとシークレットキー :基本的な認証情報 バケットポリシー :バケットレベルでのアクセス制御 アクセス制御リスト(ACL) :オブジェクトレベルでのアクセス制御 この中で、IPアドレス制限を実装するには「バケットポリシー」を利用します。 バケットポリシーによるIPアドレス制限の設定手順 1. ポリシーJSONファイルの作成 まず、以下のようなJSONファイル(例:mdx.json)を作成します: { "Version": "2008-10-17", "Statement": [ { "Sid": "BucketName", "Effect": "Allow", "Principal": { "DDN": ["*"] }, "Action": [ "s3:ListBucket", "s3:GetObject" ], "Resource": "BucketName", "Condition": { "IpAddress": { "aws:SourceIp": [ "192.168.1.1/32", "203.0.113.0/24" ] } } } ] } ポリシーの主な要素: Version : ポリシー構文のバージョン Sid : ポリシーステートメントの識別子(任意の名前) Effect : 許可または拒否(“Allow"または"Deny”) Principal : このポリシーが適用されるユーザー(DDN EXAScalerでは"DDN"を使用) Action : 許可または拒否するアクション Resource : ポリシーが適用されるリソース(バケット名) Condition : 条件(ここでIPアドレス制限を設定) 2. ポリシーの適用 s3cmdツールを使用して、作成したポリシーをバケットに適用します: ...

2025年4月24日 · 1 分 · Nakamura

Google Cloud Vision APIとGakuNin RDMを用いたTEI/XMLファイル作成アプリの試作

概要 Google Cloud Vision APIとGakuNin RDMを用いたTEI/XMLファイル作成アプリを試作しましたので備忘録です。 背景 Google Cloud Vision APIを使ってOCR結果を反映したTEI/XMLファイルを作成する環境が必要になりました。そこでバックエンドとしてGakuNin RDMを用いて、ユーザごとにファイルを管理して、OCRを実行可能な環境を試作しました。 使い方 フォルダの作成 以下にアクセスします。 https://ge-manager.vercel.app/ 画面右上から、GakuNin RDMを使ってログインします。 以下のようにプロジェクト一覧が表示されます。 適当な階層まで下り、フォルダの作成ボタンを押します。 ここでは、「sample」というフォルダを作成します。 そして、「GE Manager」のリンクを押します。 以下のようなページに遷移します。 処理の実行 今回は、「e-codices - Virtual Manuscript Library of Switzerland」の「fragm1a」を使用させていただきます。 https://www.e-codices.unifr.ch/loris/gau/gau-Fragment/gau-Fragment_frag001a.jp2/full/full/0/default/jpg 画像のURLを入力して、アップロードボタンを押します。アップロードされると、以下のような画面に変わります。 次に、「OCR実行」ボタンを押します。正しく完了すると、以下のように表示されます。 次に「TEI/XML作成」ボタンを押します。正しく完了すると、以下のようにTEI/XMLとともに表示されます。 Oxygen XML Editorでダウンロードしたファイルを表示した例です。Google Cloud Vision APIによるOCR結果を確認することができます。 GakuNin RDMのファイル 上記のプロセスで作成された各種ファイルは、GakuNin RDMのフォルダにファイルとして保存されます。 参考: URLを介してアクセス可能な画像ファイルを用意する mdx.jpのオブジェクトストレージを利用して、URLを介してアクセス可能な画像ファイルを用意する。 今回はge-editorというバケットを作成し、以下のようなファイルを用意します。 { "Version": "2008-10-17", "Statement": [ { "Sid": "ge-editor", "Effect": "Allow", "Principal": { "DDN": ["*"] }, "Action": ["s3:ListBucket", "s3:GetObject"], "Resource": "ge-editor" } ] } そして、以下を実行することで、上記のバケットにアップロードされたファイルをダウンロード可能にします。 ...

2025年4月16日 · 1 分 · Nakamura

「れきちず x Next.js」サイトにルートの登録機能を追加しました。

概要 「れきちず x Next.js」サイトにルートの登録機能を追加しました。以下が表示例です。 参考 「れきちず x Next.js」サイトについては、以下で紹介しています。 この「れきちず」を使ってルートを表示する先行事例として、以下が挙げられます。 https://codh.rois.ac.jp/edomi/route/ 今回は上記の事例を参考に、ルートを作成する機能を追加しました。 使い方 サイトにアクセスします。 https://rekichizu-next.vercel.app/ja/ 「マイルートを管理」をクリックします。 ログインが求められますので、画面右上のボタンからログインします。 「新しいルートを作成」から、ルートを作成します。 以下が編集画面です。 編集アイコンをクリックすると、ルートのタイトルおよび説明を編集できます。 モードを「追加」に設定すると、地図上でクリックした箇所にピンが立ちます。ドラッグ&ドロップで移動させることも可能です。 マーカーはドラッグ&ドロップで順序変更することができます。 インポートとエクスポート エクスポート ルートの一覧画面と編集画面にダウンロードボタンを設置しています。以下のようなJSONファイルがダウンロードされます。 { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": "1744639551563", "text": "湯島天神", "where": "神社", "type": "point" }, "geometry": { "type": "Point", "coordinates": [ 139.76809921470056, 35.707702013817155 ] } }, { "type": "Feature", "properties": { "id": "1744639379903", "text": "不忍池", "where": "池", "type": "point" }, "geometry": { "type": "Point", "coordinates": [ 139.77050681034103, 35.71210499496915 ] } }, { "type": "Feature", "properties": { "id": "1744639551563-1744639379903", "path": "[1744639551563] -> [1744639379903]", "type": "line" }, "geometry": { "type": "LineString", "coordinates": [ [ 139.76809921470056, 35.707702013817155 ], [ 139.77050681034103, 35.71210499496915 ] ] } } ] } これをgeojson.ioに貼り付けると、以下のように表示されます。 ...

2025年4月14日 · 1 分 · Nakamura

Nuxt i18nのブラウザ言語検出を無効化する方法

概要 (ChatGPTによる作成) Nuxt i18nモジュールでは、ユーザーのブラウザ言語を検出して、適切な言語のページにリダイレクトする機能があります。しかし、特定の状況ではこの機能を無効化したい場合もあります。この記事では、detectBrowserLanguage: falseを使用してブラウザ言語検出を完全に無効化する方法について解説します。 https://v8.i18n.nuxtjs.org/guide/browser-language-detection 設定方法 ブラウザの言語検出機能を無効にするには、nuxt.config.jsファイルでdetectBrowserLanguageオプションをfalseに設定します。 export default defineNuxtConfig({ // その他の設定 i18n: { // 言語検出を無効化 detectBrowserLanguage: false }, // その他の設定 }) これが役立つケース 特定のURLで直接アクセスさせたい場合 : 特定のコンテンツをユーザーが直接訪れることを意図している場合、リダイレクトが邪魔になることがあります。 クロールの最適化 : 検索エンジンのクローラーが特定の言語ページに直接アクセスできるようにしたい場合。 一貫性のあるユーザーエクスペリエンス : 例えば、リンクされた言語のページ同士を行き来するユーザーに対して、予想外のリダイレクトを避けたい場合。 まとめ detectBrowserLanguage: falseを利用することで、ユーザー体験やSEO最適化のために、リダイレクトに頼らずにサイトのアクセスを制御できます。適切な状況でこの設定を利用することで、サイトのユーザビリティを向上させることができます。 ブラウザの言語設定に影響されずに、指定した言語ページをユーザーに見てもらいたいときに、この設定を試してみてください。

2025年4月10日 · 1 分 · Nakamura

れきちずをNext.jsで使用する

概要 れきちずをNext.jsで使用する方法を調べてみましたので、備忘録です。 背景 以下の記事で、「れきちず」の使い方を紹介しました。 そして、2025年4月4日に「全国版が公開」されたことを知りました。 https://rekichizu.jp/ そこでNext.jsを用いて作成したアプリケーションへの導入にあたり、その使い方を調べてみました。 デモアプリ 以下のようなアプリケーションを試作しました。 https://rekichizu-next.vercel.app/ja/ 使用方法の調査にあたり、公式サイトで提供されている地図の切り替えや重ね合わせ機能、および検索機能などを再現することを目的としました。この実装にあたり、以下のReactライブラリを使用しました。 https://visgl.github.io/react-maplibre/ 開発メモ 検索機能 検索機能には、GeoLODのAPIを利用させていただきました。なお、「れきちず」の公式サイトでは、専用の検索APIが用いられているようでした。 https://geolod.ex.nii.ac.jp/doc/api/ react-maplibre 本ライブラリを使用して、やりたいことの多くを実現できました。一方、TerrainControlではTerrainのON/OFFと合わせてピッチを変更することが難しい?、useMapではaddLayer/removeLayerが難しい?など、いくつか苦労した点もありました。 まとめ 「れきちず」およびNext.jsを用いたアプリケーション開発にあたり、参考になりましたら幸いです。 「れきちず」の開発に関わる方々に深く感謝いたします。

2025年4月9日 · 1 分 · Nakamura

IIIFの多角形アノテーションをTEI/XMLで表現する一例

概要 IIIFの多角形アノテーションをTEI/XMLで表現する一例について紹介します。 方法 TEI/XMLでは、zoneタグとpoints属性を使用して、多角形のアノテーションを表現することができます。 https://www.tei-c.org/release/doc/tei-p5-doc/en/html/ref-teidata.point.html 例 動作確認のため、以下の記事で紹介したアノテーションツールに、TEI/XML形式でのエクスポート機能を追加しました。 具体的には、以下のようなダウンロード時のオプションを追加しました。 ダウンロード結果として得られるTEI/XMLの例は以下です。ulx, uly, lrx, lryで矩形を記述しつつ、pointsで多角形の情報を記述しています。 <?xml version="1.0" encoding="utf-8"?> <?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?> <?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?> <TEI xmlns="http://www.tei-c.org/ns/1.0"> <teiHeader> <fileDesc> <titleStmt> <title> Title </title> </titleStmt> <publicationStmt> <p> Publication Information </p> </publicationStmt> <sourceDesc> <p> Information about the source </p> </sourceDesc> </fileDesc> </teiHeader> <text> <body> <p> Some text here. </p> </body> </text> <facsimile sameAs="https://dl.ndl.go.jp/api/iiif/3437686/manifest.json"> <surface sameAs="https://dl.ndl.go.jp/api/iiif/3437686/canvas/1"> <graphic url="https://dl.ndl.go.jp/api/iiif/3437686/R0000001/full/full/0/default.jpg" sameAs="https://dl.ndl.go.jp/api/iiif/3437686/R0000001"/> <zone ulx="5314" uly="1983" lrx="5509" lry="2189" ana="Cを変更" points="5314,2087 5412,1984 5510,2087 5412,2190 5314,2087 5314,2087"/> <zone ulx="478" uly="307" lrx="1226" lry="3731" ana="校異源氏物語" points="478,3732 478,308 1227,308 1227,3732 478,3732"/> </surface> <surface sameAs="https://dl.ndl.go.jp/api/iiif/3437686/canvas/3"> <graphic url="https://dl.ndl.go.jp/api/iiif/3437686/R0000003/full/full/0/default.jpg" sameAs="https://dl.ndl.go.jp/api/iiif/3437686/R0000003"/> <zone ulx="2197" uly="3044" lrx="2731" lry="3573" ana="サンプル" points="2209,3045 2198,3551 2729,3575 2732,3062 2209,3045"/> <zone ulx="993" uly="3701" lrx="2849" lry="4095" ana="中央公論社蔵版" points="993,4096 993,3702 2849,3702 2849,4096 993,4096"/> </surface> </facsimile> </TEI> 以下は、Oxygen XML Editorで表示した例です。 ...

2025年4月8日 · 1 分 · Nakamura

IIIF画像に対して、多角形のアノテーションを付与するツールを作成しました。

概要 IIIF画像に対して、多角形のアノテーションを付与するツールを作成しました。 https://next-fb-anno.vercel.app/ 本記事では、このツールについて説明します。 使い方 以下がトップ画面です。IIIFマニフェストファイルのURLを入力します。「入力例を使用」からもお試しいただけます。『百鬼夜行図』(東京大学総合図書館所蔵)を使用しています。 以下のようなアノテーション登録画面が表示されます。 画面右上のログインボタンからログインできます。 アノテーション付与の方法は、以下の動画を参考にしてください。 https://youtu.be/9RMqaXTaOzE 開発した背景 以下の記事で説明したように、Mirador 3の mirador-annotations プラグイン向けに、Firestore用のアダプタを開発しました。 このmirador-annotations プラグインについて、多角形のアノテーション付与を行いづらいという意見がありました。 そこで、主に多角形のアノテーション付与を支援するために、本ツールを開発しました。また、アノテーション付与を実装するためのライブラリであるAnnotoriousについて、Reactライブラリが公開されていたので、この調査も兼ねて実装しました。 https://annotorious.dev/react/openseadragon-iiif/ さらに、上記の記事で紹介したmirador-annotations プラグインのFirestore用のアダプタを流用することで、同じFirebaseのサービス(AuthenticationとFirestore)を使用するようにしました。 そのため、本ツールの右上のボタンに、Miradorへのリンクを付与しました。 これにより、本ツールで編集を行い、IIIFマニフェストファイルのメタデータを含む、情報の表示にはMiradorを使用する、といった使い方が可能になるかと思います。 多角形のアノテーションを付与するための既存ツール IIIF画像に対してアノテーションを付与する機能を持つ既存ツールは数多く存在します。ここでは、IIIF画像に対して多角形のアノテーションを付与する機能を有するツールと、本ツールとの差分を紹介します。 ここでは、国立国会図書館で公開されている「和泉国絵図」を例とします。 Omeka Classic + IIIF Toolkit 以下の記事でセットアップ方法や使い方を紹介しています。 https://zenn.dev/nakamura196/books/2a0aa162dcd0eb IIIF Toolkitでは、Mirador 2が使用されており、ポリゴンアノテーションが提供されています。 今回にニーズに対しては、多角形アノテーションではなくポリゴンアノテーションである点と、Omeka Classicのセットアップ(サーバの準備や維持)が必要になる点が課題として挙げられます。 Recogito Recogitoでは傾斜したボックス形式のアノテーションを付与することはできましたが、多角形のアノテーション付与はできないようでした。 また、以下のように、pctを用いてIIIF画像にアクセスするようで、画像が表示できないケースが多くありました。 Glycerine: Image Annotation Workbench 本ツールが最も今回のニーズに合致していました。 https://glycerine.io/ おそらく本ツールと同じ「Annotorious(のver.2)」が使用されており、多角形によるアノテーションのほか、複数人による共同作業も可能でした。 唯一の課題として、登録したアノテーションの一括登録機能が提供されていませんでした。この点に対して、今回開発したツールでは、読み込んだIIIFマニフェストファイルに対して、ログインユーザが登録したユーザが付与したアノテーションを一括エクスポートする機能を設けました。 これにより、本ツールで付与したアノテーションを一括エクスポートし、他の可視化ツールで使用する、といった使い方が容易になります。 なお、以下の記事で紹介したように、Mirador 3の mirador-annotations プラグインにも付与したアノテーションをダウンロードする機能が提供されています。しかい、この機能はCanvasごとにダウンロードする仕様となっており、複数ページから構成される場合には、ページごとにダウンロードする必要がありました。 工夫点および開発メモ 本ツールの開発にあたり、工夫した点などを紹介します。 入力するIIIFマニフェストのv2およびv3対応 入力するIIIFマニフェストファイルはv2とv3、どちらでも対応できるようにしました。この実現にあたり、以下の記事で紹介した@iiif/parserを使用しました。 ...

2025年4月2日 · 1 分 · Nakamura