omeka-s
Omeka SのDocker環境における開発をサポートする専門家アシスタントです。テーマ開発(SCSS/CSS、テンプレート)、モジュール作成(PHP、イベント、データベース)、設定管理、トラブルシューティングに対応します。シンプルなCSSの調整から高度なモジュール開発まで、Omeka Sのカスタマイズに幅広く利用できます。
description の原文を見る
Expert Omeka S developer assistant for Docker-based installations. Covers theme development (SCSS/CSS, templates), module creation (PHP, events, database), configuration management, and troubleshooting. Use for Omeka S customization from simple CSS tweaks to advanced module development.
SKILL.md 本文
Omeka S 開発スキル
テーマ開発、モジュール作成、設定、トラブルシューティングに関する包括的な知識を持つ Omeka S 開発エキスパートアシスタントです。このスキルにより、シンプルな CSS 調整から高度なモジュール開発まで、あらゆる複雑さのレベルで Omeka S カスタマイズをサポートできます。
コア情報
インストール形式
- Docker ベース: Omeka S はコンテナで実行
- コンテナ名:
omeka-s-app(アプリケーション)、omeka-s-db(データベース) - ベースパス: コンテナ内の
/var/www/html/ - バージョン: Omeka S 4.0.4+ (確認:
docker exec omeka-s-app cat /var/www/html/application/Module.php | grep VERSION)
ファイル操作パターン
すべてのファイル操作は Docker コマンドを使用します:
# ファイル読み込み
docker exec omeka-s-app cat /var/www/html/{path}
# ディレクトリ一覧
docker exec omeka-s-app ls -la /var/www/html/{path}
# ファイル検索
docker exec omeka-s-app find /var/www/html/{path} -name "pattern"
# コンテナへのファイルコピー
docker cp {local-path} omeka-s-app:/var/www/html/{path}
# コピー後のパーミッション修正
docker exec omeka-s-app chown -R www-data:www-data /var/www/html/{path}
ディレクトリ構造
/var/www/html/
├── application/ # Omeka S コアコード (変更しない)
│ ├── asset/ # Admin CSS、JS、フォント
│ ├── config/ # コア設定
│ ├── src/ # PHP ソース (名前空間付き)
│ └── view/ # デフォルトテンプレート (テーマでオーバーライドするためにコピー)
│ ├── common/ # 共有テンプレート
│ ├── layout/ # レイアウトテンプレート
│ └── omeka/site/ # サイトテンプレート
├── config/ # インストール設定
│ ├── database.ini # データベース認証 (ボリュームへのシンボリックリンク)
│ └── local.config.php # ローカル設定
├── modules/ # インストール済みモジュール
├── themes/ # インストール済みテーマ
├── volume/ # 永続的なデータ
│ ├── config/ # 永続的な設定
│ └── files/ # アップロード済みメディア
│ ├── original/
│ ├── large/
│ ├── medium/
│ └── square/
├── vendor/ # Composer 依存関係
└── index.php # エントリーポイント
サイト設定とコンテンツ表示
重要なデータベースリレーション
重要: アイテム、アイテムセット、サイトは複数のデータベーステーブルで接続されています。すべてのリレーションが正しくない限り、コンテンツは表示されません。
アイテムをサイトに表示させる
アイテムを公開サイトに表示させるには、以下のすべてが真である必要があります:
-
アイテムが公開状態である
UPDATE resource SET is_public = 1 WHERE resource_type = 'Omeka\\Entity\\Item'; -
アイテムがサイトに割り当てられている (
item_siteテーブル経由)INSERT INTO item_site (item_id, site_id) SELECT i.id, 1 FROM item i ON DUPLICATE KEY UPDATE site_id = VALUES(site_id); -
アイテムがオープンなアイテムセットに含まれている (アイテムセットを使用している場合)
UPDATE item_set SET is_open = 1; -
アイテムセットがサイトにリンクされている (
site_item_setテーブル経由)INSERT INTO site_item_set (site_id, item_set_id, position) SELECT 1, id, id FROM item_set ON DUPLICATE KEY UPDATE position = VALUES(position); -
サイトのアイテムプールがアイテムセットを含んでいる (
siteテーブルの JSON 配列)UPDATE site SET item_pool = '[1,2,3,4,5]' WHERE id = 1; -- または全アイテムセット: SELECT GROUP_CONCAT(id) FROM item_set; -- 結果をコピー UPDATE site SET item_pool = '[ここに貼り付け]' WHERE id = 1;
主要なデータベーステーブル
site テーブル:
homepage_id: サイトのホームページとして表示するページ (NULL の場合、「ページなし」メッセージを表示)item_pool: このサイトで利用可能なアイテムセット ID の JSON 配列slug: サイトの URL スラッグis_public: サイト表示設定
site_setting テーブル:
- キーバリュー設定を PHP シリアライズ形式で保存
pagination_per_page: ページあたりのアイテム数 (デフォルト: 25)browse_heading_property_term: アイテムタイトルのプロパティ (例: "dcterms:title")browse_body_property_term: アイテム説明のプロパティbrowse_defaults_public_items: ソート順序の JSON (sort_by と sort_order を含む)
site_page_block テーブル:
data: ページブロックの JSON 設定- 一般的なブロックタイプ: browsePreview、html、itemShowcase、asset
- ブラウズプレビューブロックオプション:
{ "resource_type": "items" または "item_sets", "query": "", "limit": "12", "components": ["resource-heading", "resource-body", "thumbnail"], "heading": "セクションタイトル", "link-text": "すべて表示" }
item_site テーブル (結合テーブル):
- アイテムをサイトにリンク (多対多)
- 重要: このエントリがないとアイテムはサイトに表示されません
site_item_set テーブル (結合テーブル):
- アイテムセットをサイトにリンク (多対多)
- 並び順のための
positionフィールドを持つ
item_set テーブル:
is_open: ブール値 - FALSE (0) の場合、サイトとアイテムが公開状態でも内部のアイテムは公開されません- 表示に重要: アイテムを表示するために TRUE (1) である必要があります
ホームページの設定
ページをホームページとして設定するには:
UPDATE site SET homepage_id = (SELECT id FROM site_page WHERE slug = 'welcome' LIMIT 1) WHERE id = 1;
またはページ ID で直接:
UPDATE site SET homepage_id = 1 WHERE id = 1;
その後、キャッシュをクリアして再起動:
docker exec omeka-s-app rm -rf /var/www/html/application/data/cache/*
docker restart omeka-s-app
メディアとサムネイルシステム
サムネイルの仕組み
アイテムは primary_media_id でサムネイルを表示:
- アイテムはメディアレコードを指す
primary_media_idを持つ - メディアレコードは
has_thumbnailsブール値フラグを持つ - 物理的なサムネイルファイルは
/files/large/、/files/medium/、/files/square/に保存 - ファイル名形式:
{storage_id}.jpg(media.storage_id と一致)
アイテムセットは primary_media_id を使用しない:
- アイテムセットは自動的に最初のアイテムのサムネイルを使用
- 手動によるサムネイル割り当ては不要
アセット対メディア:
assetテーブル: 手動でアップロードされたアセット (サイトロゴ、バナー)mediaテーブル: アイテムの添付 (画像、PDF、ドキュメント)- 異なるシステムです - 混同しないでください!
アイテムにプライマリメディアを割り当てる
-- 全アイテムの最初のメディアをプライマリとして設定
UPDATE item i
JOIN (
SELECT item_id, MIN(id) as first_media
FROM media
GROUP BY item_id
) m ON i.id = m.item_id
SET i.primary_media_id = m.first_media;
確認:
SELECT COUNT(*) FROM item WHERE primary_media_id IS NOT NULL;
PDF サムネイル生成
要件:
- Ghostscript (
gs) インストール済み - PDF サポート有効な ImageMagick
- パスワード保護されていない PDF
Ghostscript のインストール (不足している場合):
docker exec omeka-s-app apt-get update
docker exec omeka-s-app apt-get install -y ghostscript
ImageMagick ポリシーの更新:
ImageMagick はセキュリティ上の理由から PDF 処理をデフォルトでブロックします。ポリシーを更新:
docker exec omeka-s-app bash -c 'cat > /etc/ImageMagick-6/policy.xml << "EOF"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policymap [
<!ELEMENT policymap (policy)*>
<!ATTLIST policymap xmlns CDATA #FIXED "">
<!ELEMENT policy EMPTY>
<!ATTLIST policy xmlns CDATA #FIXED "" domain NMTOKEN #REQUIRED
name NMTOKEN #IMPLIED pattern CDATA #IMPLIED rights NMTOKEN #IMPLIED
stealth NMTOKEN #IMPLIED value CDATA #IMPLIED>
]>
<policymap>
<policy domain="resource" name="memory" value="256MiB"/>
<policy domain="resource" name="map" value="512MiB"/>
<policy domain="resource" name="width" value="16KP"/>
<policy domain="resource" name="height" value="16KP"/>
<policy domain="resource" name="area" value="128MB"/>
<policy domain="resource" name="disk" value="1GiB"/>
<policy domain="coder" rights="read|write" pattern="PDF" />
<policy domain="module" rights="read|write" pattern="{PS,PDF,XPS}" />
</policymap>
EOF'
PDF 処理テスト:
docker exec omeka-s-app bash -c '
PDF_FILE=$(ls /var/www/html/files/original/*.pdf 2>/dev/null | head -1)
if [ -n "$PDF_FILE" ]; then
convert "${PDF_FILE}[0]" -thumbnail 200x200 /tmp/test-thumb.jpg
if [ -f /tmp/test-thumb.jpg ]; then
echo "✅ PDF processing works!"
else
echo "❌ PDF processing failed"
fi
fi
'
すべての PDF のサムネイル生成:
スクリプトを作成:
#!/bin/bash
# /tmp/regenerate-pdf-thumbnails.sh として保存
ORIGINAL_DIR="/var/www/html/files/original"
LARGE_DIR="/var/www/html/files/large"
MEDIUM_DIR="/var/www/html/files/medium"
SQUARE_DIR="/var/www/html/files/square"
success=0
failed=0
for pdf in $ORIGINAL_DIR/*.pdf; do
if [ -f "$pdf" ]; then
filename=$(basename "$pdf")
name="${filename%.*}"
# パスワード保護された PDF をスキップ
if file "$pdf" | grep -q "password protected"; then
echo "SKIP: $name (password protected)"
((failed++))
continue
fi
# 3 つのサムネイルサイズを生成
if convert "${pdf}[0]" -resize "800x800>" "$LARGE_DIR/${name}.jpg" 2>/dev/null && \
convert "${pdf}[0]" -resize "200x200>" "$MEDIUM_DIR/${name}.jpg" 2>/dev/null && \
convert "${pdf}[0]" -resize "200x200^" -gravity center -extent 200x200 "$SQUARE_DIR/${name}.jpg" 2>/dev/null; then
echo "✓ $name"
((success++))
else
echo "✗ $name"
((failed++))
fi
fi
done
echo "Success: $success | Failed: $failed"
アップロードして実行:
docker cp /tmp/regenerate-pdf-thumbnails.sh omeka-s-app:/tmp/
docker exec omeka-s-app chmod +x /tmp/regenerate-pdf-thumbnails.sh
docker exec omeka-s-app /tmp/regenerate-pdf-thumbnails.sh
データベースを更新:
UPDATE media SET has_thumbnails = 1
WHERE media_type IN ('application/pdf', 'image/jpeg', 'image/png');
サムネイルトラブルシューティング
サムネイルが表示されない場合:
media.has_thumbnails = 1をそのメディア用に確認item.primary_media_idが正しいメディアを指していることを確認/files/medium/にサムネイルファイルが正しいstorage_id.jpg名で存在することを確認- ファイルパーミッション (
www-data:www-data) を確認 - キャッシュをクリア:
docker exec omeka-s-app rm -rf /var/www/html/application/data/cache/*
パスワード保護された PDF:
- パスワードなしでサムネイルを生成できません
- プレースホルダー画像 (audio.png またはdefault.png) が表示されます
- 自動化されたソリューションはありません
メディアタイプのカバー:
- ✅ JPEG、PNG: 常にサムネイルあり
- ✅ PDF: パスワード保護されていない場合、生成可能
- ❌ オーディオ (MP3、MP4): 視覚的コンテンツなし - プレースホルダーを使用
- ❌ ビデオ: ffmpeg が必要 - 複雑なセットアップ
一般的なクエリ
サムネイルのカバレッジを確認:
SELECT
media_type,
COUNT(*) as total,
SUM(has_thumbnails) as with_thumbs,
COUNT(*) - SUM(has_thumbnails) as without_thumbs
FROM media
GROUP BY media_type
ORDER BY (COUNT(*) - SUM(has_thumbnails)) DESC;
プライマリメディアのないアイテムを検索:
SELECT COUNT(*) FROM item WHERE primary_media_id IS NULL;
サムネイルのないアイテムを検索:
SELECT i.id, i.primary_media_id, m.has_thumbnails
FROM item i
LEFT JOIN media m ON i.primary_media_id = m.id
WHERE m.has_thumbnails = 0 OR i.primary_media_id IS NULL;
テーマ開発
テーマ構造 (公式パターン)
themes/{theme-name}/
├── config/
│ └── theme.ini # 必須 - テーマメタデータと設定
├── asset/
│ ├── css/ # コンパイル済み CSS
│ │ ├── style.css
│ │ └── print.css
│ ├── sass/ # SASS ソース (オプションだが推奨)
│ │ ├── style.scss # メインエントリーポイント
│ │ ├── print.scss
│ │ ├── _base.scss
│ │ ├── _screen.scss
│ │ └── _desktop.scss
│ ├── js/
│ │ └── {theme}.js
│ ├── img/
│ └── fonts/
├── view/
│ ├── layout/
│ │ └── layout.phtml # メインレイアウトテンプレート
│ ├── common/ # 共有パーシャル
│ └── omeka/site/ # コアテンプレートをオーバーライド
│ ├── item/
│ │ ├── show.phtml
│ │ └── browse.phtml
│ └── ...
├── composer.json # PHP 依存関係 (オプション)
├── package.json # SASS コンパイル用 Node 依存関係
├── gulpfile.js # ビルドシステム (SASS を使用している場合)
└── theme.jpg # テーマサムネイル
CSS/SCSS ビルドプロセス
重要: 公式 Omeka S テーマは SCSS ソースファイルを Gulp でコンパイルします。CSS ファイルを直接編集しないで、SCSS ソースを編集して再ビルドしてください。
ビルドシステム構造
デフォルトテーマは以下を使用:
- SCSS ソース:
asset/sass/ディレクトリ - ビルドツール: Gulp (
gulpfile.js) - 出力:
asset/css/ディレクトリ (コンパイル、オートプレフィックス、圧縮) - 依存関係:
package.jsonは npm パッケージを定義
SCSS アーキテクチャ (デフォルトテーマパターン)
asset/sass/
├── style.scss # メインエントリー - すべてのパーシャルをインポート
├── print.scss # 印刷スタイルエントリー
├── _normalize.scss # CSS リセット
├── _base.scss # 変数、タイポグラフィ、色
├── _screen.scss # モバイルファーストスタイル
└── _desktop.scss # デスクトップオーバーライド (min-width: 800px)
style.scss のインポート順:
@import "normalize"; // リセット
@import "susy"; // グリッドシステム
@import "base"; // 変数とベーススタイル
@media screen {
@import "screen"; // モバイルファーストスタイル
}
@media screen and (min-width:800px) {
@import "desktop"; // デスクトップ拡張
}
CSS 変更のワークフロー
1. コンテナからテーマファイルをダウンロード:
docker cp omeka-s-app:/var/www/html/themes/default /tmp/omeka-theme
cd /tmp/omeka-theme
2. ビルド依存関係をインストール:
npm install
# sass モジュールが不足している場合:
npm install sass
3. SCSS ソースファイルを編集:
# 適切なパーシャルを編集:
nano asset/sass/_screen.scss # モバイル/ベーススタイル用
nano asset/sass/_desktop.scss # デスクトップスタイル用
nano asset/sass/_base.scss # 変数/色用
4. SCSS を CSS にコンパイル:
npx gulp css
# または変更を監視:
npx gulp css:watch
5. コンパイル済み CSS をコンテナにアップロード:
docker cp asset/css/style.css omeka-s-app:/var/www/html/themes/default/asset/css/
docker exec omeka-s-app chown www-data:www-data /var/www/html/themes/default/asset/css/style.css
6. Omeka キャッシュをクリア:
docker exec omeka-s-app rm -rf /var/www/html/application/data/cache/*
_base.scss の一般的な SCSS 変数
// スペース
$spacing-s: 7.5px;
$spacing-m: 15px;
$spacing-l: 30px;
// 色
$gray: #ababab;
$bold: darken($gray, 20%); // #676767
$light: lighten($gray, 20%); // #dedede
$bg: lighten($gray, 30%); // #f8f8f8
$link: #920b0b; // アクセント色
// タイポグラフィ
$base-font-size: 20px;
$base-line-height: 30px;
例: リストをグリッドレイアウトに変換
asset/sass/_screen.scss を編集 (モバイルファースト):
ul.resource-list {
list-style-type: none;
padding-left: 0;
display: grid;
grid-template-columns: 1fr; // モバイルは 1 列
gap: $spacing-l;
}
ul.resource-list .resource {
border: 1px solid $light;
padding: 0;
background: #fff;
display: flex;
flex-direction: column;
&:hover {
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
}
ul.resource-list .resource img {
width: 100%;
height: auto;
max-height: 250px;
object-fit: cover;
}
// タブレット用 2 列
@media screen and (min-width: 600px) {
ul.resource-list {
grid-template-columns: repeat(2, 1fr);
}
}
asset/sass/_desktop.scss を編集 (デスクトップ拡張):
ul.resource-list {
grid-template-columns: repeat(3, 1fr); // 800px 以上で 3 列
}
// 大型スクリーン用 4 列
@media screen and (min-width: 1200px) {
ul.resource-list {
grid-template-columns: repeat(4, 1fr);
}
}
Gulpfile.js 設定
デフォルトテーマはこの Gulp セットアップを使用:
var gulp = require('gulp');
gulp.task('css', function () {
var sass = require('gulp-sass')(require('sass'));
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
return gulp.src('./asset/sass/*.scss')
.pipe(sass({
outputStyle: 'compressed',
includePaths: ['node_modules/susy/sass']
}).on('error', sass.logError))
.pipe(postcss([
autoprefixer()
]))
.pipe(gulp.dest('./asset/css'));
});
gulp.task('css:watch', function () {
gulp.watch('./asset/sass/*.scss', gulp.parallel('css'));
});
機能:
- 圧縮出力: CSS ミニファイド
- オートプレフィックス: ベンダープレフィックスを自動追加
- Susy グリッド: レガシーグリッドシステム (オプション)
- ウォッチモード: 変更時に自動再コンパイル
クイック CSS 編集 (ビルドシステムなし)
軽微な修正の場合:
- コンテナのコンパイル済み CSS を直接編集 (大規模な変更には非推奨)
- theme.ini 設定オプションで色、スペースを使用
- サイト管理 → Appearance → [Theme] → Custom CSS でカスタム CSS を追加
直接編集例:
# ダウンロード、編集、アップロード
docker cp omeka-s-app:/var/www/html/themes/default/asset/css/style.css ./
# style.css を編集
docker cp style.css omeka-s-app:/var/www/html/themes/default/asset/css/
docker exec omeka-s-app chown www-data:www-data /var/www/html/themes/default/asset/css/style.css
注: CSS の直接編集は SCSS が再コンパイルされた場合に失われます。
ビルドの問題のトラブルシューティング
"npm: command not found" がコンテナに表示される:
- ホストマシンで CSS をコンパイルしてアップロード
- コンテナは本番環境で Node.js を必要としません
SCSS コンパイルエラー:
- 編集したファイルの構文を確認
- すべての変数が定義されていることを確認
- @import パスが正しいことを確認
変更が表示されない:
- ブラウザキャッシュをクリア (Ctrl+Shift+R)
- Omeka キャッシュをクリア:
docker exec omeka-s-app rm -rf /var/www/html/application/data/cache/* - コンテナを再起動:
docker restart omeka-s-app - ファイルパーミッションを確認:
docker exec omeka-s-app ls -la /var/www/html/themes/default/asset/css/
ビルド中の非推奨警告:
- SASS/Gulp 警告は古いテーマでは正常
- 出力 CSS は引き続き正しく機能
- ビルドが失敗しない限り無視できます
theme.ini (必須設定)
[info]
name = "テーマ名"
description = "テーマ説明"
author = "著者名"
author_link = "https://example.com"
theme_link = "https://github.com/..."
version = "1.0.0"
omeka_version_constraint = "^4.0.0"
tags = "tag1, tag2"
[config]
elements.accent_color.name = "accent_color"
elements.accent_color.type = "color"
elements.accent_color.attributes.value = "#ff6600"
elements.logo.name = "logo"
elements.logo.type = "asset"
elements.logo.attributes.accept = "image/*"
layout.phtml (メインレイアウトテンプレート)
layout.phtml の主要なパターン:
<!DOCTYPE html>
<html lang="<?php echo $this->lang(); ?>">
<head>
<meta charset="utf-8">
<title><?php echo $this->pageTitle($site->title(), 2); ?></title>
<?php // CSS を読み込み ?>
<?php $this->headLink()->prependStylesheet($this->assetUrl('css/style.css')); ?>
<?php $this->headLink()->prependStylesheet('//fonts.googleapis.com/css?family=Lato'); ?>
<?php echo $this->headLink(); ?>
<?php // JavaScript を読み込み ?>
<?php $this->headScript()->prependFile($this->assetUrl('js/default.js')); ?>
<?php echo $this->headScript(); ?>
<?php // テーマ設定 ?>
<?php $accentColor = $this->themeSetting('accent_color'); ?>
</head>
<body>
<header>
<?php // ロゴ ?>
<?php if ($logo = $this->themeSetting('logo')): ?>
<img src="<?php echo $this->themeSettingAssetUrl('logo'); ?>" alt="Logo">
<?php endif; ?>
<?php // サイトタイトル ?>
<h1><?php echo $site->title(); ?></h1>
<?php // ナビゲーション ?>
<?php echo $this->navigation()->menu()->renderMenu(null, [
'maxDepth' => $this->themeSetting('nav_depth')
]); ?>
<?php // 検索 ?>
<?php echo $this->partial('common/search-form'); ?>
</header>
<main>
<?php // ページコンテンツ ?>
<?php echo $this->content; ?>
</main>
<footer>
<?php echo $this->themeSetting('footer_content'); ?>
</footer>
</body>
</html>
一般的なビューヘルパー ($this-> で使用)
$this->assetUrl('path/file.ext')- テーマアセット URL$this->themeSetting('setting_name')- テーマ設定値を取得$this->themeSettingAssetUrl('logo')- テーマ設定アセット URL$this->url('route', ['param' => 'value'])- URL を生成$this->translate('text')- 文字列を翻訳$this->escapeHtml($text)- HTML エスケープ$this->partial('common/template-name')- パーシャルをレンダリング$this->pageTitle($text, $level)- ページタイトルを設定$this->thumbnail($resource, ['thumbnailType' => 'square'])- サムネイルを表示$this->lang()- 現在の言語コード$this->navigation()->menu()- ナビゲーションヘルパー$this->headLink()- CSS リンクヘルパー$this->headScript()- JavaScript ヘルパー
テーマカスタマイズのワークフロー
1. シンプルな CSS 変更 (SASS なし):
# 現在の CSS を読み込み
docker exec omeka-s-app cat /var/www/html/themes/default/asset/css/style.css > style.css
# ローカルで style.css を編集
# ... 変更を加える ...
# コピーバック
docker cp style.css omeka-s-app:/var/www/html/themes/default/asset/css/style.css
# 必要に応じてキャッシュをクリア
docker exec omeka-s-app rm -rf /var/www/html/application/data/cache/*
2. SASS 変更 (推奨):
# SASS ファイルを抽出
docker exec omeka-s-app tar -czf /tmp/sass.tar.gz -C /var/www/html/themes/default/asset sass
docker cp omeka-s-app:/tmp/sass.tar.gz .
tar -xzf sass.tar.gz
# ローカルで SASS ファイルを編集
# ... *.scss ファイルを変更 ...
# コンパイル (Node/gulp がローカルにある場合)
npm install
gulp
# またはコンテナに SASS をコピーバックしてコンパイル (ツールがインストール済みの場合)
docker cp sass omeka-s-app:/var/www/html/themes/default/asset/
docker exec -w /var/www/html/themes/default omeka-s-app npm install
docker exec -w /var/www/html/themes/default omeka-s-app gulp
3. テンプレート変更:
# カスタマイズするテンプレートを検索
docker exec omeka-s-app find /var/www/html/application/view/omeka/site -name "*.phtml"
# テンプレートをテーマにコピー
docker exec omeka-s-app mkdir -p /var/www/html/themes/default/view/omeka/site/item
docker exec omeka-s-app cp /var/www/html/application/view/omeka/site/item/show.phtml \
/var/www/html/themes/default/view/omeka/site/item/show.phtml
# ダウンロード、編集、アップロード
docker cp omeka-s-app:/var/www/html/themes/default/view/omeka/site/item/show.phtml .
# ... show.phtml を編集 ...
docker cp show.phtml omeka-s-app:/var/www/html/themes/default/view/omeka/site/item/show.phtml
4. 新しいテーマを作成:
# ローカルでテーマ構造を作成
mkdir -p my-theme/{config,asset/{css,js,img},view/layout}
# theme.ini を作成 (上記パターンを参照)
# layout.phtml を作成 (上記パターンを参照)
# style.css を作成
# コンテナにコピー
docker cp my-theme omeka-s-app:/var/www/html/themes/
docker exec omeka-s-app chown -R www-data:www-data /var/www/html/themes/my-theme
# テーマが Omeka 管理画面に表示されます
モジュール開発
モジュール構造 (公式パターン)
modules/{ModuleName}/
├── Module.php # 必須 - メインモジュールクラス
├── config/
│ ├── module.ini # 必須 - モジュールメタデータ
│ └── module.config.php # モジュール設定 (推奨)
├── src/ # 名前空間付き PHP コード
│ ├── Controller/ # コントローラー
│ │ └── IndexController.php
│ ├── Form/ # フォーム
│ │ └── ConfigForm.php
│ ├── Entity/ # Doctrine エンティティ
│ ├── Service/ # サービスファクトリー
│ ├── View/
│ │ └── Helper/ # ビューヘルパー
│ └── Job/ # バックグラウンドジョブ
├── view/
│ ├── {module-name}/ # モジュールテンプレート
│ │ └── index/
│ │ └── index.phtml
│ └── common/ # 共有テンプレート (モジュール名でプレフィックス!)
├── asset/
│ ├── js/
│ │ └── {module-name}.js
│ └── css/
│ └── {module-name}.css
├── data/
│ ├── install/
│ │ └── schema.sql # データベーススキーマ
│ └── scripts/
│ └── upgrade.php # アップグレードロジック
├── language/ # 翻訳
│ ├── template.pot
│ └── en_US.mo
├── test/ # ユニットテスト
├── vendor/ # Composer 依存関係 (git-ignored)
├── composer.json
├── LICENSE.txt
└── README.md
module.ini (必須)
[info]
name = "モジュール名"
description = "モジュール説明"
tags = "tag1, tag2"
license = "Apache-2.0"
author = "著者名"
author_link = "https://example.com"
module_link = "https://github.com/..."
support_link = "https://github.com/.../issues"
configurable = true
version = "1.0.0"
omeka_version_constraint = "^4.0.0"
dependencies = "OtherModule"
Module.php (必須クラス)
<?php
namespace ModuleName;
use Omeka\Module\AbstractModule;
use Laminas\View\Model\ViewModel;
use Laminas\ServiceManager\ServiceLocatorInterface;
use Laminas\EventManager\SharedEventManagerInterface;
use Laminas\EventManager\Event;
class Module extends AbstractModule
{
/**
* モジュール設定配列を返す
*/
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
/**
* モジュールをインストール (テーブルを作成、デフォルトを設定)
*/
public function install(ServiceLocatorInterface $services)
{
$connection = $services->get('Omeka\Connection');
$sql = file_get_contents(__DIR__ . '/data/install/schema.sql');
$connection->exec($sql);
// デフォルト設定を設定
$settings = $services->get('Omeka\Settings');
$settings->set('modulename_setting', 'default_value');
}
/**
* モジュールをアンインストール (テーブルを削除、設定をクリア)
*/
public function uninstall(ServiceLocatorInterface $services)
{
$settings = $services->get('Omeka\Settings');
$settings->delete('modulename_setting');
$connection = $services->get('Omeka\Connection');
$connection->exec('DROP TABLE IF EXISTS modulename_table');
}
/**
* モジュールをアップグレード
*/
public function upgrade($oldVersion, $newVersion, ServiceLocatorInterface $services)
{
require_once __DIR__ . '/data/scripts/upgrade.php';
}
/**
* 設定フォームビューを返す (configurable=true の場合)
*/
public function getConfigForm(ViewModel $view)
{
$services = $this->getServiceLocator();
$settings = $services->get('Omeka\Settings');
$view->setVariable('setting_value', $settings->get('modulename_setting'));
return $view;
}
/**
* 設定フォーム送信を処理
*/
public function handleConfigForm(AbstractController $controller)
{
$services = $this->getServiceLocator();
$settings = $services->get('Omeka\Settings');
$params = $controller->params()->fromPost();
$settings->set('modulename_setting', $params['modulename_setting']);
return true;
}
/**
* イベントリスナーをアタッチ
*/
public function attachListeners(SharedEventManagerInterface $sharedEventManager)
{
// アイテムビューイベントをリッスン
$sharedEventManager->attach(
'Omeka\Controller\Site\Item',
'view.show.after',
[$this, 'handleItemShowAfter']
);
// フォームイベントをリッスン
$sharedEventManager->attach(
'Omeka\Form\ItemForm',
'form.add_elements',
[$this, 'addFormElements']
);
}
/**
* イベントハンドラー例
*/
public function handleItemShowAfter(Event $event)
{
$view = $event->getTarget();
$item = $view->item;
// カスタムコンテンツを追加
echo $view->partial('common/modulename-display', ['item' => $item]);
}
public function addFormElements(Event $event)
{
$form = $event->getTarget();
$form->add([
'name' => 'modulename_field',
'type' => 'Text',
'options' => [
'label' => 'カスタムフィールド',
],
]);
}
}
module.config.php (推奨設定)
<?php
return [
'view_manager' => [
'template_path_stack' => [
dirname(__DIR__) . '/view',
],
],
'controllers' => [
'invokables' => [
'ModuleName\Controller\Index' => Controller\IndexController::class,
],
],
'router' => [
'routes' => [
'modulename' => [
'type' => 'Segment',
'options' => [
'route' => '/modulename[/:action]',
'defaults' => [
'controller' => 'ModuleName\Controller\Index',
'action' => 'index',
],
],
],
],
],
'view_helpers' => [
'invokables' => [
'moduleNameHelper' => View\Helper\ModuleNameHelper::class,
],
],
'form_elements' => [
'invokables' => [
'ModuleName\Form\ConfigForm' => Form\ConfigForm::class,
],
],
];
一般的な Omeka S イベント (attachListeners 用)
コントローラーイベント:
view.show.before/view.show.after- リソース表示の前後view.browse.before/view.browse.after- ブラウズページの前後view.search.query- 検索クエリを変更view.layout- レイアウトにコンテンツを追加
フォームイベント:
form.add_elements- フォーム要素を追加form.add_input_filters- 入力フィルターを追加
API イベント:
api.search.query- API 検索を変更api.find.query- API 検索を変更api.create.pre/api.create.post- 作成の前後api.update.pre/api.update.post- 更新の前後api.delete.pre/api.delete.post- 削除の前後
リソースイベント:
rep.resource.display_values- リソース表示を変更rep.resource.values- リソース値を変更
モジュール開発ワークフロー
1. モジュール構造を作成:
# ローカルでモジュールディレクトリを作成
mkdir -p MyModule/{config,src,view,asset/{js,css},data/install}
# Module.php を作成 (上記テンプレートを参照)
# config/module.ini を作成 (上記テンプレートを参照)
# config/module.config.php を作成 (オプションだが推奨)
# コンテナにコピー
docker cp MyModule omeka-s-app:/var/www/html/modules/
docker exec omeka-s-app chown -R www-data:www-data /var/www/html/modules/MyModule
# モジュールが Omeka 管理画面 > モジュールに表示されます
2. 既存モジュールを変更:
# モジュールをダウンロード
docker cp omeka-s-app:/var/www/html/modules/ModuleName ./ModuleName
# ファイルを編集
# ... 変更を加える ...
# 変更をアップロード
docker cp ModuleName omeka-s-app:/var/www/html/modules/
docker exec omeka-s-app chown -R www-data:www-data /var/www/html/modules/ModuleName
# 管理画面でモジュールを無効化して再度有効化して再読み込み
3. モジュールをデバッグ:
# ログをチェック
docker exec omeka-s-app cat /var/www/html/logs/application.log
# config/local.config.php でエラーログを有効化
docker exec omeka-s-app cat /var/www/html/config/local.config.php
# 追加: 'logger' => ['log' => true, 'priority' => \Laminas\Log\Logger::DEBUG]
設定管理
database.ini
場所: /var/www/html/config/database.ini → /var/www/html/volume/config/database.ini へのシンボリックリンク
user = "omekas"
password = "omekas"
dbname = "omekas"
host = "db"
;port =
;unix_socket =
;log_path =
変更するには:
docker exec omeka-s-app bash -c 'cat > /var/www/html/config/database.ini << EOF
user = "newuser"
password = "newpass"
dbname = "newdb"
host = "db"
EOF'
local.config.php
場所: /var/www/html/config/local.config.php
一般的な設定:
<?php
return [
'logger' => [
'log' => true, // ログを有効化
'priority' => \Laminas\Log\Logger::DEBUG, // ログレベル
],
'thumbnails' => [
'types' => [
'large' => ['constraint' => 800],
'medium' => ['constraint' => 200],
'square' => ['constraint' => 200, 'options' => ['gravity' => 'center']],
],
'thumbnailer_options' => [
'imagemagick_dir' => '/usr/bin',
],
],
'translator' => [
'locale' => 'en_US',
],
'mail' => [
'transport' => [
'type' => 'smtp',
'options' => [
'name' => 'localhost',
'host' => 'smtp.example.com',
'port' => 587,
],
],
],
'service_manager' => [
'aliases' => [
'Omeka\File\Store' => 'Omeka\File\Store\Local',
'Omeka\File\Thumbnailer' => 'Omeka\File\Thumbnailer\ImageMagick',
],
],
];
トラブルシューティング
一般的な問題と解決策
1. モジュールが表示されない:
# module.ini が存在し有効であることを確認
docker exec omeka-s-app cat /var/www/html/modules/ModuleName/config/module.ini
# ファイルパーミッションを確認
docker exec omeka-s-app ls -la /var/www/html/modules/ModuleName
# パーミッションを修正
docker exec omeka-s-app chown -R www-data:www-data /var/www/html/modules/ModuleName
# Omeka バージョン制約を確認
# module.ini で omeka_version_constraint = "^4.0.0" であることを確認
2. テーマが適用されない:
# theme.ini が存在することを確認
docker exec omeka-s-app cat /var/www/html/themes/themename/config/theme.ini
# バージョン制約を確認
# インストール済みバージョンに omeka_version_constraint が一致することを確認
# キャッシュをクリア
docker exec omeka-s-app rm -rf /var/www/html/application/data/cache/*
docker compose restart omeka-s
3. CSS/JS 変更が表示されない:
# ブラウザキャッシュをクリア
# ハード更新 (Ctrl+Shift+R または Cmd+Shift+R)
# ファイルが実際に更新されたことを確認
docker exec omeka-s-app cat /var/www/html/themes/default/asset/css/style.css | head -20
# layout.phtml のアセット URL を確認
docker exec omeka-s-app grep headLink /var/www/html/themes/default/view/layout/layout.phtml
# local.config.php でキャッシュをチェック
docker exec omeka-s-app grep cache /var/www/html/config/local.config.php
4. データベース接続エラー:
# database.ini 認証を確認
docker exec omeka-s-app cat /var/www/html/config/database.ini
# データベース接続をテスト
docker exec omeka-s-app php -r "
\$pdo = new PDO('mysql:host=db;dbname=omekas', 'omekas', 'omekas');
echo 'Connected successfully';
"
# データベースコンテナが実行中か確認
docker ps | grep db
# データベースログを確認
docker logs omeka-s-db
5. アップロード/ファイルの問題:
# ファイルディレクトリのパーミッションを確認
docker exec omeka-s-app ls -la /var/www/html/volume/files/
# パーミッションを修正
docker exec omeka-s-app chown -R www-data:www-data /var/www/html/volume/files/
# 利用可能な容量をチェック
docker exec omeka-s-app df -h /var/www/html/volume/
# サムネイル生成を確認
docker exec omeka-s-app which convert # ImageMagick
6. モジュールインストールエラー:
# アプリケーションログを確認
docker exec omeka-s-app cat /var/www/html/logs/application.log
# PHP エラーを確認
docker logs omeka-s-app 2>&1 | tail -50
# Module.php 構文を確認
docker exec omeka-s-app php -l /var/www/html/modules/ModuleName/Module.php
# 依存関係を確認
docker exec omeka-s-app cat /var/www/html/modules/ModuleName/config/module.ini | grep dependencies
7. ビュー/テンプレートエラー:
# テンプレートパスを確認
docker exec omeka-s-app find /var/www/html/themes/default/view -name "*.phtml"
# テンプレート構文を確認 (PHP)
docker exec omeka-s-app php -l /var/www/html/themes/default/view/layout/layout.phtml
# パーシャルエラーをチェック
docker logs omeka-s-app 2>&1 | grep "partial"
ベストプラクティス
命名規約
- モジュール: CamelCase (MyAwesomeModule)
- テーマ: lowercase-with-hyphens (my-theme)
- ファイル: 小文字、PHP クラスはアンダースコア、テンプレートはハイフン
- 名前空間: PSR-4 に従う (ModuleName\Controller\IndexController)
ファイル整理
- テーマを themes ディレクトリに完全に含める
- モジュールを modules ディレクトリに完全に含める
- コアアプリケーションファイルを変更しない
- カスタムコードにバージョン管理を使用
パフォーマンス
- ループ内のデータベースクエリを最小化
- Omeka の組み込みキャッシュを使用
- アップロード前に画像を最適化
- 適切なサムネイルサイズを使用
- 重い リソースを遅延読み込み
セキュリティ
- 常に出力をエスケープ:
$this->escapeHtml() - ユーザー入力を検証
- データベースクエリはプリペアドステートメントを使用
- 機密操作の前にパーミッションをチェック
- Laminas セキュリティプラクティスに従う
保守性
- カスタムコードを文書化
- Omeka コーディング標準に従う
- モジュールを焦点化 (単一責任)
- Omeka バージョン間でテスト
- アップグレードパスを提供
クイックリファレンス
必須コマンド
# Omeka バージョンを確認
docker exec omeka-s-app cat /var/www/html/application/Module.php | grep VERSION
# インストール済みモジュールを一覧表示
docker exec omeka-s-app ls /var/www/html/modules/
# インストール済みテーマを一覧表示
docker exec omeka-s-app ls /var/www/html/themes/
# ログをチェック
docker logs omeka-s-app --tail=50
docker exec omeka-s-app cat /var/www/html/logs/application.log
# キャッシュをクリア
docker exec omeka-s-app rm -rf /var/www/html/application/data/cache/*
# Omeka を再起動
docker compose restart omeka-s
# データベースをバックアップ
docker exec omeka-s-db mariadb-dump -u omekas -pomekas omekas > backup.sql
# データベースを復元
docker exec -i omeka-s-db mariadb -u omekas -pomekas omekas < backup.sql
ファイルパスリファレンス
- テーマ:
/var/www/html/themes/ - モジュール:
/var/www/html/modules/ - 設定:
/var/www/html/config/ - アップロード:
/var/www/html/volume/files/ - ログ:
/var/www/html/logs/ - アプリケーション:
/var/www/html/application/ - デフォルトテンプレート:
/var/www/html/application/view/omeka/site/
開始方法
Omeka S 開発をサポートする際:
- タスクを理解: テーマ、モジュール、設定、トラブルシューティングのいずれかを明確にする
- 現在の状態を確認: 変更する前に関連ファイルを読む
- Docker コマンドを使用: すべての操作は
docker execまたはdocker cpで実行 - パターンに従う: 公式 Omeka の構造と規約を使用
- 変更をテスト: 期待通りに機能することを確認
- 文書化: 何が変更されたかと理由を説明
注意: Omeka S は Laminas Framework (旧 Zend) を使用します。多くのパターンは Laminas MVC 規約に従います。
追加リソース
- 公式ドキュメント: https://omeka.org/s/docs/
- 開発者ドキュメント: https://omeka.org/s/docs/developer/
- GitHub: https://github.com/omeka/omeka-s
- フォーラム: https://forum.omeka.org/
- モジュールリポジトリ: https://omeka.org/s/modules/
- テーマリポジトリ: https://omeka.org/s/themes/
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- szweibel
- ライセンス
- MIT
- 最終更新
- 2026/1/31
Source: https://github.com/szweibel/claude-skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。