はじめに
Odooでは「モデル」がデータの設計図です。取引先や受注と同じように、ブログ記事もモデルで管理され、データベースに構造化された形で保存されます。
モデルはOdooのデータ設計の中核を成します。フィールド定義、他モデルとの関係、そしてビジネスロジックがここに含まれるため、開発者も業務担当者もモデルの仕組みを理解しておく必要があります。
本稿では website_blog モジュール内の blog.post モデルに焦点を当てます。サイト上のブログ機能の中核で、UIでの記事作成、API経由の自動投稿、カスタム表示など、あらゆるブログ関連の操作はこのモデルを中心に動きます。
blog.post モデルとは何か
blog.post モデルは、Odoo上の個別のブログ記事を表します。1レコード=1記事で、ウェブサイトに表示される単位そのものです。
このモデルは website_blog モジュールに属し、blog.blog(ブログのコンテナ)や blog.tag(タグ分類)と連携して動作します。Odooで記事を新規作成・編集すると、その操作は blog.post レコードの作成や更新として扱われます。
blog.post はいくつかのミックスインを継承しています。たとえば mail.thread によりチャッターやフォロワー機能を利用し、website.published.mixin により公開・非公開の挙動を制御します。拡張時には継承元の動きを理解しておくと安全です。
blog.post は抽象モデルでも一時モデルでもなく通常のストアドモデルです。データベースに永続保存され、APIから create/read/update/search が可能です。
モデル内の主要フィールド
以下は blog.post で特に重要なフィールドの一覧です。各フィールドの役割を押さえることで、記事運用やカスタマイズがスムーズになります。
1. name(タイトル)
型: Char。記事のタイトルを格納します。必須で、一覧やフォーム、ウェブ上の表示に使われます。ブラウザタブや検索結果にも反映される重要なフィールドです。
2. blog_id(所属ブログ)
型: Many2one (blog.blog)。記事が属するブログを参照します。企業サイトで複数のブログ(ニュース、製品情報、技術記事など)を運用する際、セクション分けに使います。
3. subtitle(サブタイトル)
型: Char。短い副題や補足フレーズです。記事ページのタイトル下や一覧で使われ、SEOや読者の理解を助けます。
4. content(本文)
型: Html。記事本文のリッチコンテンツを保持します。テキスト、画像、ウェブスニペットなどを含み、主要なコンテンツ領域です。
5. teaser(自動抜粋)
型: Text。本文から自動生成される抜粋です。ブログ一覧などでのプレビューに使われ、読み取り専用の計算フィールドです。
6. teaser_manual(手動抜粋)
型: Text。自動抜粋を上書きするための手動要約です。冒頭文と異なる要約を表示したいときに有効です。
7. author_id(著者)
型: Many2one (res.partner)。記事の執筆者を参照します。複数著者の運営や著者別一覧に便利です。
8. author_name(著者表示名)
型: Char。author_id に基づく表示名で読み取り専用。著者情報がない場合の代替文字列にもなります。
9. author_avatar(著者アイコン)
型: Binary。著者のアバター画像。記事横に表示することで信頼感を高めます(任意)。
10. is_published(公開状態:表示)
型: Boolean。記事がサイトに表示されているかどうかの計算済みフラグ。読み取り専用で、実際の切り替えは別フィールドで行います。
11. website_published(公開操作)
型: Boolean。公開/下書きを切り替えるための書き込み可能なフィールドです。Trueで公開、Falseで下書き扱いになります。is_published はこれに従います。
12. post_date(公開日)
型: Datetime。訪問者に表示する公開日時。並び替えやスケジュール投稿に利用します。未来日時を設定して予約公開も可能です。
13. published_date(公開確定日時)
型: Datetime。実際に公開された日時を自動記録します。website_published が True になったときにセットされ、分析に使えます。
14. active(アクティブフラグ)
型: Boolean。論理削除用のフラグです。False にするとデフォルト表示から隠れ、履歴を残したまま非表示にできます。
15. tag_ids(タグ)
型: Many2many (blog.tag)。記事の分類タグ。フィルタやグルーピングに使います。タグは階層化されたカテゴリを持てます。
16. visits(閲覧数)
型: Integer。閲覧カウンター。読み取り専用で、訪問時にインクリメントされます。人気記事の判定や分析に利用します。
17. website_url(記事URL)
型: Char。ウェブ上のフルパス。読み取り専用。形式は /blog/{blog-seo-name}-{blog-id}/{post-seo-name}-{post-id} のようになります。
18. cover_properties(カバー設定)
型: Text。カバー画像の位置やオーバーレイなどをJSONで保持します。フロントエンド表示に使われる設定です。
19. header_visible(ヘッダー表示)
型: Boolean。記事ページでサイトヘッダーを表示するかどうか。フルワイド表示や埋め込み表示に便利です。
20. footer_visible(フッター表示)
型: Boolean。記事ページでサイトフッターを表示するかどうか。header_visible と組み合わせて使います。
21. seo_name(URLスラッグ)
型: Char。SEOに適したURLスラッグ。空ならタイトルから自動生成されます。例: my-post-title が記事のURLに用いられます。
22. website_meta_title(メタタイトル)
型: Char。検索結果やブラウザタブに表示されるメタタイトル。SEO対策として重要です。
23. website_meta_description(メタディスクリプション)
型: Text。検索スニペットに表示される説明文。表示上は150〜160文字程度を目安に書くと最適です。
24. website_meta_keywords(メタキーワード)
型: Char。かつてのSEO用キーワード。現在は重要度が低いものの、システムによっては参照されます。
25. create_date(作成日)
型: Datetime。レコード作成日時。Odooが自動管理し、レポートや監査に利用します。
26. create_uid(作成者)
型: Many2one (res.users)。レコードを作成したユーザー。自動設定で読み取り専用です。
27. write_date(更新日)
型: Datetime。最終更新日時。自動管理され、最新更新を追跡するのに役立ちます。
28. write_uid(最終更新者)
型: Many2one (res.users)。最後に編集したユーザー。読み取り専用です。
29. display_name(表示名)
型: Char。計算された表示名で、Many2one のドロップダウンや検索結果で使われます。読み取り専用です。
30. website_id(サイト所属)
型: Many2one (website)。マルチサイト構成で記事が属するウェブサイト。未設定なら全サイトで表示される場合があります。
業務フローでの活用例
1. コンテンツマーケティングとSEO対策
マーケティング担当者は blog.post を使って記事を作成し、website_meta_title や website_meta_description、seo_name を最適化して検索流入を狙います。本文は content に保存され、タグでテーマごとに整理します。
2. 複数ブログの運用
企業がニュース、製品情報、技術ブログなど複数のブログを運用する場合、各 blog.blog に紐づく blog.post を使い分けます。blog_id により訪問者はカテゴリごとに閲覧できます。
3. API経由のコンテンツ連携
外部システムやヘッドレスCMS、既存のCMSからの移行では XML-RPC や JSON-RPC を通じて blog.post を作成・更新します。OdooのAPIは create/read/update/search をサポートするため、自動同期やバッチ投入が可能です。
4. 予約投稿(スケジューリング)
post_date を将来日時に設定しつつ website_published を True にすることで、指定日時に記事を公開できます。コンテンツカレンダー運用やキャンペーンに便利です。
5. 複数執筆者での共同作業
author_id と mail.thread により、担当者の割当やフォロワーへの通知、チャッターでの内部コメントが利用できます。公開前のレビューや承認フローとも相性が良いです。
開発者による拡張方法
開発者は Odoo の継承機構を使って blog.post を拡張します。拡張のパターンはいくつかあります。
モデル継承の使い方
モデルを拡張するには _inherit = 'blog.post' を使います。新しいフィールドを追加したり、メソッドを上書きして制約を加えたりできます。変更は別モジュールにまとめておくとアップグレード時に安全です。mail.thread や website.published.mixin の動作を考慮して実装してください。
フィールド追加の注意点
継承モデルに新しいフィールドを定義する際は適切な型を選びます(Char、Many2one、Boolean、Integer、Text、Selection など)。読み時間や独自カテゴリーなどのメタデータはフィールド追加で扱い、ビューに展開して運用します。競合を避けるためにカスタムフィールドは x_ プレフィックスを付ける運用が一般的です。
Python側の拡張
create / write / unlink をオーバーライドして独自ロジックを挿入できますが、super() を呼んで元の処理を維持するのが重要です。website_published や post_date に関連する計算フィールドがあるため、URL生成などをカスタムしたい場合は _compute_website_url のオーバーライドを検討してください。
Odoo Studio の活用
コードを書かずにフィールドを追加できる Odoo Studio は素早いカスタマイズに便利です。ただし複雑なロジックや外部API連携、カスタムビューが必要な場合は専用モジュールで実装するほうが保守性が高くなります。blog.post は API 経由でも完全に操作可能です。
推奨される運用・実装のコツ
- 各記事に website_meta_title と website_meta_description を必ず設定しましょう。検索結果でのクリック率向上に直結します。
- 自動生成の teaser で満足できない場合は teaser_manual を使って手動で要約を用意すると一覧での訴求力が上がります。
- 重要記事には seo_name を明示的に設定し、特殊文字や長すぎる文字列は避けてわかりやすいスラッグにしてください。
- API を使って公開操作を行う場合、書き込みは website_published に対して行ってください。is_published は読み取り専用なので更新操作には使えません。
- カテゴリ分けのために tag_ids を活用し、タグは事前に作成して使い回すことで分類の一貫性を保ちます。
よくある失敗パターン
- is_published に書き込もうとすること。is_published は計算フィールドで書き込み不可です。公開・非公開の切り替えは website_published を操作してください。
- blog_id を設定し忘れること。blog_id は記事の所属を決める重要なフィールドで、未設定だと正しく表示されない場合があります。
- website_meta_description を空欄にすること。検索エンジンがページ内のランダムなテキストを抜粋してしまうことがあるため、150〜160文字程度の明確な説明を入れてください。
- core メソッドを super() を呼ばずに上書きしてしまうこと。これにより website mixin や mail.thread の挙動が壊れる恐れがあります。
- 同一ブログ内で seo_name が重複すること。URL衝突を招くため、Odooの自動生成に任せるか一意性を保証してください。
まとめ
blog.post モデルは Odoo のブログ機能の核となる存在で、記事の本文、メタ情報、公開状態までを管理します。blog.blog や blog.tag との関係を理解すると、設定や拡張、外部連携が格段にやりやすくなります。
コンテンツ担当が運用する場合でも、開発者が API 統合を作る場合でも、blog.post の仕組みをしっかり押さえておけば時間と手戻りを大幅に減らせます。
Odoo導入のサポートが必要ですか?
Dasolo は Odoo の導入、カスタマイズ、最適化を支援します。API連携やモジュール開発を得意とし、blog.post を含む Odoo のデータ設計に関する豊富な実務経験があります。
Odoo の導入支援やカスタムモジュール、外部連携でお困りでしたら、お気軽にご相談ください。 デモを予約する プロジェクトについて詳しくお話ししましょう。