はじめに
プリザンターにはテナント管理画面からブラウザのタブに表示される「HTMLタイトル」を自由にカスタマイズできる機能があります。「トップ」「サイト」「レコード」の3つの画面区分ごとに、キーワードを組み合わせてタイトルを設定できます。
この記事では、HTMLタイトル機能の仕組みをソースコードから読み解き、使えるキーワードや決定ロジックを詳しく解説します。さらに、テナント管理画面だけでは変更できないケースについて、スクリプトやサーバスクリプトで対応する方法も紹介します。
HTMLタイトルとは
HTMLタイトルは <title> タグに設定される文字列で、ブラウザのタブやブックマークに表示されます。
プリザンターでは、テナント管理画面(管理 → テナントの管理)から以下の3つの画面区分ごとに設定できます。
| 設定項目 | 対象画面 | デフォルト値 |
|---|---|---|
| HTMLタイトル(トップ) | トップページ、管理画面など | [ProductName] |
| HTMLタイトル(サイト) | フォルダ・テーブル・Wiki・ダッシュボードの一覧画面 | [ProductName] |
| HTMLタイトル(レコード) | レコードの編集画面 | [ProductName] |
使用できるキーワード
テナント管理画面のHTMLタイトル欄では、以下のキーワードが使えます。実際の画面表示時にそれぞれの値へ自動的に置換されます。
| キーワード | 置換される値 | 例 |
|---|---|---|
[ProductName] |
製品名 | プリザンター |
[TenantTitle] |
テナントのタイトル | 株式会社〇〇 |
[SiteTitle] |
サイトのタイトル | 顧客管理 |
[RecordTitle] |
レコードのタイトル | 田中太郎 |
[Action] |
現在のアクション名 | 一覧、編集、新規作成 など |
[ProductName] は App_Data/Displays/ProductName.json で定義されている値です。日本語環境では「プリザンター」、英語環境では「Pleasanter」が表示されます。
設定例
いくつかのパターンを見てみましょう。
| 設定値 | 表示例 |
|---|---|
[ProductName] |
プリザンター |
[TenantTitle] - [ProductName] |
株式会社〇〇 - プリザンター |
[SiteTitle] | [TenantTitle] |
顧客管理 | 株式会社〇〇 |
[RecordTitle] - [SiteTitle] |
田中太郎 - 顧客管理 |
[SiteTitle]([Action]) |
顧客管理(一覧) |
[Action] キーワードの詳細
[Action] キーワードは現在の画面操作に応じた名前に置換されます。ソースコードを見ると、以下のアクションに対応しています。
private static string GetActionName(Context context)
{
switch (context.Action)
{
case "new":
return Displays.New(context: context);
case "edit":
return Displays.Edit(context: context);
case "index":
return Displays.Index(context: context);
case "calendar":
return Displays.Calendar(context: context);
case "crosstab":
return Displays.Crosstab(context: context);
case "gantt":
return Displays.Gantt(context: context);
case "burndown":
return Displays.BurnDown(context: context);
case "timeseries":
return Displays.TimeSeries(context: context);
case "analy":
return Displays.Analy(context: context);
case "kamban":
return Displays.Kamban(context: context);
case "imagelib":
return Displays.ImageLib(context: context);
case "trashbox":
return Displays.TrashBox(context: context);
default:
return string.Empty;
}
}
日本語環境でのアクション名は以下のとおりです。
| アクション | 表示名 |
|---|---|
new |
新規作成 |
edit |
編集 |
index |
一覧 |
calendar |
カレンダー |
crosstab |
クロス集計 |
gantt |
ガントチャート |
burndown |
バーンダウンチャート |
timeseries |
時系列チャート |
analy |
分析チャート |
kamban |
カンバン |
imagelib |
画像ライブラリ |
trashbox |
ごみ箱 |
上記以外のアクション(ダッシュボードの index 等)では空文字列になります。
タイトル決定ロジック
HTMLタイトルがどの設定値を使うかは、context.Controller と context.Id の値で決まります。ソースコードを見てみましょう。
public static string TitleText(Context context, SiteSettings ss)
{
switch (context.Controller)
{
case "items":
case "publishes":
if (context.Id == 0)
{
return FormattedHtmlTitle(
context: context,
ss: ss,
format: context.HtmlTitleTop);
}
else if (context.Id == context.SiteId)
{
return FormattedHtmlTitle(
context: context,
ss: ss,
format: context.HtmlTitleSite);
}
else
{
return FormattedHtmlTitle(
context: context,
ss: ss,
format: context.HtmlTitleRecord);
}
default:
return FormattedHtmlTitle(
context: context,
ss: ss,
format: context.HtmlTitleTop);
}
}
フローチャートにすると次のようになります。
フォーマット処理
キーワードの置換処理も確認してみましょう。
private static string FormattedHtmlTitle(
Context context, SiteSettings ss, string format, bool publishes = false)
{
return context.HasPermission(ss: ss)
? Strings.CoalesceEmpty(
format?
.Replace("[ProductName]", Displays.ProductName(context: context))
.Replace("[TenantTitle]", context.TenantTitle)
.Replace("[SiteTitle]", context.SiteTitle)
.Replace("[RecordTitle]", context.CanRead(ss: ss)
? context.RecordTitle
: Displays.ProductName(context: context))
.Replace("[Action]", GetActionName(context: context)),
context.TenantTitle,
Displays.ProductName(context: context))
: Displays.ProductName(context: context);
}
ここから読み取れるポイントをまとめます。
| ポイント | 内容 |
|---|---|
| 権限チェック | サイトへのアクセス権限がない場合は [ProductName] のみ表示 |
| 読み取り権限 |
[RecordTitle] はレコードの読み取り権限がある場合のみ表示。ない場合は [ProductName] に置換 |
| フォールバック | フォーマット結果が空の場合は [TenantTitle] → [ProductName] の順でフォールバック |
テナント管理では変更できないケース
テナント管理のHTMLタイトル設定では対応できないケースがあります。
| ケース | 理由 |
|---|---|
| ログイン画面のタイトル | Controller が items でも publishes でもないため、常にHTMLタイトル(トップ)が使われる。ただしログイン画面ではテナント情報がロードされないため、結果的に [ProductName] 固定になる |
| 条件に応じた動的なタイトル | キーワード置換のみで条件分岐はできない |
| 項目の値をタイトルに含める |
[RecordTitle] 以外の項目値(分類や状況など)をタイトルに表示できない |
| テナント管理画面以外の管理画面 | ユーザー管理、グループ管理などは常にHTMLタイトル(トップ)が適用される |
これらのケースは、スクリプトやサーバスクリプトで対応できます。
スクリプトでHTMLタイトルを変更する
サイトのテーブル管理 → スクリプトに JavaScript を追加することで、document.title を自由に変更できます。
例1:一覧画面でビューモードをタイトルに表示する
一覧画面でカレンダーやカンバンなどのビューモードを切り替えたとき、今どのビューを見ているのかをタイトルに表示します。
$p.events.on_grid_load = function () {
const action = $('#Action').val();
const actions = {
index: '一覧',
calendar: 'カレンダー',
crosstab: 'クロス集計',
gantt: 'ガントチャート',
burndown: 'バーンダウンチャート',
timeseries: '時系列チャート',
analy: '分析チャート',
kamban: 'カンバン',
imagelib: '画像ライブラリ',
trashbox: 'ごみ箱',
};
const viewMode = actions[action] || action;
document.title = viewMode + ' | ' + document.title;
};
出力先を「一覧」に設定してください。[Action] キーワードでも同様のことができますが、スクリプトなら表示文言を自由にカスタマイズできます。
例2:編集画面で状況をタイトルに表示する
レコードの編集画面で、状況(ステータス)の値をタイトルに含めます。
$p.events.on_editor_load = function () {
const status = $p.getControl('Status').find('option:selected').text();
if (status) {
document.title = '[' + status + '] ' + document.title;
}
};
レコードを開くと、タブに「[完了] 田中太郎 - 顧客管理」のように状況付きのタイトルが表示されます。
出力先を「新規作成」「編集」に設定してください。
例3:一覧画面でフィルタ条件をタイトルに反映する
一覧画面で現在のビュー名をタイトルに付加します。複数のビューを切り替えて使う運用で、今どのビューを表示しているか一目で分かるようになります。
$p.events.on_grid_load = function () {
const viewName = $('.current-view').text().trim();
if (viewName) {
document.title = viewName + ' - ' + document.title;
}
};
サーバスクリプトでHTMLタイトルを変更する
サーバスクリプトから直接 document.title を変更することはできませんが、context.AddResponse の Invoke メソッドを使って、クライアント側の関数を呼び出すことができます。スクリプトと組み合わせることで、サーバ側で算出した値をタイトルに反映できます。
例4:サーバスクリプトで算出した値をタイトルに反映する
たとえば、レコードに関連する集計値や業務ロジックに基づくラベルをタイトルに含めたいケースを考えてみましょう。
まず、スクリプト側にタイトルを設定する関数を用意します。
function setCustomTitle(prefix) {
if (prefix) {
document.title = prefix + ' | ' + document.title;
}
}
出力先を「新規作成」「編集」に設定してください。
次に、サーバスクリプト(条件:画面表示の前)で context.AddResponse を使って関数を呼び出します。
try {
const classA = model.ClassA;
if (classA) {
context.AddResponse('Invoke', 'setCustomTitle', classA);
}
} catch (e) {
context.Log(e.stack);
}
条件を「画面表示の前」に設定してください。model.ClassA の部分は、タイトルに表示したい項目に合わせて変更します。
例5:期限切れレコードにタイトルで警告する
期限日を過ぎたレコードに対して、タイトルに警告を表示する例です。
スクリプト側:
function setOverdueTitle(message) {
document.title = message + ' ' + document.title;
}
サーバスクリプト(条件:画面表示の前):
try {
const completionTime = model.CompletionTime;
const status = model.Status;
if (completionTime && status < 900) {
const deadline = new Date(completionTime);
const now = new Date();
if (deadline < now) {
context.AddResponse('Invoke', 'setOverdueTitle', '【期限超過】');
}
}
} catch (e) {
context.Log(e.stack);
}
レコードの期限日を過ぎていて、かつ状況が完了(900)未満の場合、タブに「【期限超過】 田中太郎 - 顧客管理」のように表示されます。
まとめ
テナント管理画面のHTMLタイトル設定でできることと、スクリプトで拡張できることを整理します。
| やりたいこと | 方法 |
|---|---|
| トップ・サイト・レコードごとにタイトルを設定する | テナント管理画面のHTMLタイトル設定 |
| キーワードで動的に値を表示する |
[ProductName]、[TenantTitle]、[SiteTitle]、[RecordTitle]、[Action]
|
| 項目の値をタイトルに含める | スクリプトで document.title を変更 |
| 条件に応じてタイトルを切り替える | サーバスクリプト + スクリプトの組み合わせ |
| ビューモードやフィルタ条件をタイトルに表示する | スクリプトで document.title を変更 |
テナント管理画面の設定だけでも多くのケースに対応できますが、より細かな制御が必要な場合はスクリプトやサーバスクリプトと組み合わせることで柔軟にカスタマイズできます。