今回の記事では以下のAPEXアプリケーションを使って、テキスト・メッセージの使い方について説明します。
説明に使用するAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-text-message.zip
テキスト・メッセージはひとつの言語(例えば日本語)だけでも良いのですが、今回は、英語、日本語、簡体中国語、韓国語の4種類のメッセージを作成しています。
テキスト・メッセージの作成は、共有コンポーネントのテキスト・メッセージより行います。
テキスト・メッセージの作成には、名前、言語、JavaScriptで使用、テキストおよびコメントを指定します。アプリケーションがテキスト・メッセージを取り出す際には、セッション言語に一致するテキスト・メッセージが取り出されます。
テキスト・メッセージをJavaScriptから参照する場合は、JavaScriptで使用をオンにします。
テキスト・メッセージはサブスクリプションをサポートしています。アプリケーションに設定したテキスト・メッセージを別のアプリケーションで使用する場合は、最初にマスターとなるアプリケーションを作成して、そのアプリケーションにテキスト・メッセージを作成し、マスターとなるアプリケーションからテキスト・メッセージをサブスクライブするとよいでしょう。
テキスト・メッセージT_GREETING0として、APEX 24.2以前で扱えるテキスト・メッセージを作成します。24.2以前では置換文字列として、位置パラメータ%0、%1、... %9を使用できます。
T_GREETING0の言語ごとに、以下のテキストを設定します。
英語: I hope this message finds you well. <b>This is %1 from %0 Corporation.</b>
日本語: いつも大変お世話になっております。<b>%0株式会社の %1 です。</b>
簡体中国語: 非常感谢您长期以来的支持与信任。<b>我是 %0公司的 %1。</b>
韓国語: 평소 베풀어 주신 성원에 깊이 감사드립니다. <b>%0회사 %1 입니다.</b>
T_GREETING1として、APEX 24.2で扱えるテキスト・メッセージを作成します。24.2より置換文字列に名前を使えます。そのため、置換文字列の位置を気にする必要がありません。
英語: I hope this message finds you well. <b>This is %sender from %company Corporation.</b>
日本語: いつも大変お世話になっております。<b>%company株式会社の %sender です。</b>
簡体中国語: 非常感谢您长期以来的支持与信任。<b>我是 %company公司的 %sender。</b>
韓国語: 평소 베풀어 주신 성원에 깊이 감사드립니다. <b>%company회사 %sender 입니다.</b>
APEXアプリケーションにサポート言語を追加します。言語ごとのテキスト・メッセージが不要な場合は、翻訳の追加は不要です。その際は作成するテキスト・メッセージの言語として、アプリケーションのプライマリ言語(通常は日本語)を指定します。
共有コンポーネントのアプリケーション翻訳を開きます。
アプリケーション言語の定義を開きます。
翻訳アプリケーションとして、APEXの(ワークスペースではなく)インスタンス全体で使用されていないアプリケーションIDを指定します。以下のSELECT文で、未使用のアプリケーションIDを見つけることができます。
with all_application_ids as (
-- 最小のアプリケーションIDから最大までの連番
select (select min(application_id) from apex_applications) + level - 1 as n
from dual
connect by level <=
(
select max(application_id) - min(application_id) + 1
from apex_applications
)
)
select n as unused_application_id
from all_application_ids
where n not in (select application_id from apex_applications) -- 使用中のIDを除く
order by n
実際には適当な数値を入力して、エラーが発生しない値を見つける、といった指定の仕方になるかと思います。アプリケーション言語マッピングとして、英語(en)、中国語(中国)(zh-cn)、韓国語(ko)を作成します。
今回はセッション言語の切り替えが行えれば良いので、アプリケーションの翻訳までは行いません。アプリケーションを翻訳する場合は、テキストのシードやテキストの翻訳、アプリケーションのパブリッシュといった作業を実施します。
テキスト・メッセージには、会社名と担当者名に置き換えるパラメータを含めています。それらを置き換える値を、アプリケーション定義の置換に設定します。
会社名として使用する置換文字列としてG_COMPANY、置換値としてOracle Breadsを設定します。担当者名はG_SENDER、置換値としてMugiを設定します。
実際にAPEXアプリケーションにテキスト・メッセージを表示してみます。
APEX 24.2以前は、以下の置換文字列にてテキスト・メッセージに置き換えます。静的メッセージで位置パラメータを置き換える手段はありません。
&APP_TEXT$T_GREETING0.
静的コンテンツのリージョンにテキスト・メッセージT_GREETING0を表示します。
画面の表示は以下になります。会社名、担当者名が抜けているため、このままでは使用できません。24.2以前でテキスト・メッセージに含まれる位置パラメータを置き換えるには、PL/SQLによる動的コンテンツかJavaScriptによるコーディングが必要です。
テキスト・メッセージに含まれるHTMLタグはデフォルトでエスケープされます。HTMLをそのまま解釈させたい場合は、置換文字列名の末尾に!RAWを加えます。
&APP_TEXT$T_GREETING0!RAW.
セキュリティの脆弱性につながるため、テキスト・メッセージが勝手に書き換えられることが無いように注意します。
APEX 24.2では、テキスト・メッセージに位置パラメータの代わりに置換文字列を設定できます。テキスト・メッセージT_GREETING1は、以下のように置換文字列%companyおよび%userを含んでいます。
APEX 24.2では、以下の指定でテキスト・メッセージの置き換えができます。
いつも大変お世話になっております。<b>%company株式会社の %sender です。</b>
APEX 24.2では、以下の指定でテキスト・メッセージの置き換えができます。
&{T_GREETING1 sender=&G_SENDER. company=&G_COMPANY. }!RAW.
画面の表示は以下になります。会社名%company、担当者名%senderが、置換文字列G_COMPANYおよびG_SENDERの値に置き換えられています。
英語での表示を確認します。開発者ツールバーのセッションよりセッション・オーバーライドを開きます。
セッション・オーバーライドの有効化をオンにし、アプリケーション言語をオン、言語に英語
(en)を選択して、設定を保存します。
韓国語(ko)での表示は以下になります。
アプリケーション言語の切り替えは、アプリケーション定義のグローバリゼーションで定義します。このアプリケーションでは、アプリケーションのプライマリ言語を日本語(ja)に固定しているため、必ず日本語のテキスト・メッセージが表示されます。
ユーザーのセッションごとにアプリケーションの表示言語を切り替える場合は、アプリケーション言語の導出元を変更します。言語の切り替え方法については、以前の記事「Oracle APEXアプリケーションのグローバル化(5) - 言語の切り替え」が参考になります。
PL/SQLの動的コンテンツでテキスト・メッセージを表示します。
APEX 24.2以前ではAPEX_LANG.MESSAGEを呼び出して、テキスト・メッセージを表示する文字列に置き換えます。24.2以前では会社名や担当者名は位置パラメータ%0および%1にて指定されているため、引数:G_COMPANYおよび:G_SENDERの順番は重要です。
declare
l_clob clob;
begin
l_clob := apex_lang.message('T_GREETING0', :G_COMPANY, :G_SENDER);
return l_clob;
end;
declare
l_clob clob;
begin
l_clob := apex_lang.get_message('T_GREETING1',
apex_t_varchar2(
'sender', :G_SENDER,
'company', :G_COMPANY
)
);
return l_clob;
end;
動的コンテンツの表示は同じです。
続いて、JavaScriptによるテキスト・メッセージの参照方法を紹介します。
テキスト・メッセージのJavaScriptで使用をオンにすると、ページがロードされるときにJavaScriptからテキスト・メッセージが参照できるように、テキスト・メッセージが設定されます。
こうするとテキスト・メッセージをロードするためのコードは不要になりますが、テキスト・メッセージを参照しないページにも、JavaScriptで使用がオンになっているテキスト・メッセージがロードされます。JavaScript APIとしてapex.lang.loadMessagesおよびapex.lang.loadMessagesIfNeededが提供されているので、テキスト・メッセージが参照される頻度を鑑みて、JavaScriptで使用を設定します。
置換文字列G_COMPANYとG_SENDERの値をJavaScriptから参照できるように、ページ・プロパティのJavaScriptのファンクションおよびグローバル変数の宣言に以下を記述します。
const COMPANY = '&G_COMPANY.';
const SENDER = '&G_SENDER.';
JavaScriptによる表示は、静的コンテンツのリージョンに行うことにします。ソースのHTMLコードに以下を記述します。
<div id="greeting-pre242"></div>
APEX 24.2以前では、apex.lang.formatMessageを以下のように呼び出します。静的コンテンツのリージョンに、テキスト・メッセージT_GREETING0の置換値が表示されます。
document.getElementById("greeting-pre242").innerHTML = apex.lang.formatMessage( "T_GREETING0", COMPANY, SENDER );
テキスト・メッセージのJavaScriptで使用がオフのときは、以下のコードを実行します。
const promise = apex.lang.loadMessages( ["T_GREETING0"] );
promise.done( () => {
document.getElementById("greeting-pre242").innerHTML = apex.lang.formatMessage( "T_GREETING0", COMPANY, SENDER );
}).fail( () => {
apex.debug.error("Could not get messages.");
});
または、以下のコードを実行します。
apex.lang.loadMessagesIfNeeded( ["T_GREETING0"], () => {
document.getElementById("greeting-pre242").innerHTML = apex.lang.formatMessage( "T_GREETING0", COMPANY, SENDER );
});
どのコードでも、静的コンテンツへの表示は同じです。
APEX 24.2では、apex.lang.formatMessageに、テキスト・メッセージに含まれる置換文字列の置換値を、JSONドキュメントとして与えます。
document.getElementById("greeting-242").innerHTML = apex.lang.formatMessage( "T_GREETING1", { sender: SENDER, company: COMPANY } );
テキスト・メッセージのJavaScriptで使用がオフのときは、以下のコードを実行します。
const promise242 = apex.lang.loadMessages( ["T_GREETING1"] );
promise242.done( () => {
document.getElementById("greeting-242").innerHTML = apex.lang.formatMessage( "T_GREETING1", { sender: SENDER, company: COMPANY } );
}).fail( () => {
apex.debug.error("Could not get messages.");
});
または、以下のコードを実行します。
apex.lang.loadMessagesIfNeeded( ["T_GREETING1"], () => {
document.getElementById("greeting-242").innerHTML = apex.lang.formatMessage("T_GREETING1", { sender: SENDER, company: COMPANY });
});
APEX 24.2でも、静的コンテンツへの表示は同じです。
例えば、担当者名を青色(u-hot-text)に変更します。アプリケーション定義のG_SENDERを以下に変更します。
<span class="u-hot-text">Mugi</span>
JavaScriptでHTMLタグをエスケープせずそのまま出力するには、apex.lang.formatMessageの代わりにapex.lang.formatMessageNoEscapeを呼び出します。
JavaScriptによる表示はHTMLタグがそのまま表示され、担当者名の色は変わりません。
例えば、コードを以下のように変更します。
apex.lang.loadMessagesIfNeeded( ["T_GREETING0"], () => {
document.getElementById("greeting-pre242").innerHTML = apex.lang.formatMessageNoEscape( "T_GREETING0", COMPANY, SENDER );
});
HTMLタグのエスケープを抑止すると、JavaScriptによる表示でも担当者名は青くなります。
動的にHTMLコンテンツを生成する際に、生成するHTMLの安全性については開発者が担保する必要があります。HTMLタグが含まれていなければ、innerHTMLではなくinnerTextに書き込むといった対応も考えられます。
最後にAPEX 24.2のページ・デザイナに、テキスト・メッセージ・ピッカーが追加されています。有効にするには、ページ・デザイナのユーティリティの表示より、テキスト・メッセージ・ピッカーを有効にします。
プロパティ・エディタで文字列を入力する箇所に、地球のアイコンのボタンが表示されます。
アイコンをクリックすると、作成済みのテキスト・メッセージとテキストが一覧されます。
Oracle APEXのテキスト・メッセージとAPEX 24.2で新規に追加された機能の紹介は以上になります。
今回作成したアプリケーションのように、メインのアプリケーションと追加された翻訳が同期していないと、アプリケーションをエクスポートするときに警告が表示されるようになりました。これも、APEX 24.2の新機能です。
翻訳されたアプリケーションが同期していないと、アプリケーションのエクスポート時に翻訳が失われることがあります。警告を表示することにより、翻訳アプリケーションを安全にエクスポートできます。
今回の記事は以上になります。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完