2020年10月20日火曜日

Servicenowのポータルでのナレッジ記事の表示順を任意に指定できる様にするためのカスタマイズ(完成版)

さて長くなってしまったこのシリーズ。完成版としてやっといろいろな謎が解けて実装ができた。

前提知識については次の過去記事を参照願いたい。
Servicenowのポータルでのナレッジ記事の表示順の謎
Servicenowのポータルでのナレッジ記事の表示順をタイトル順にするためのカスタマイズ
Servicenowの既存のテーブルにカラムを追加する
Servicenowのポータルでのナレッジ記事の表示順を任意に指定できる様にするためのカスタマイズ(今のところ出来ませんでした)

本記事のカスタマイズは②と③が適用済みの環境を前提とさせていただくのでその点はご了承ください。①は必要であれば予備知識として。④は失敗例なので特に読む必要ありません。

結論としては②で作成したCopy of KB Category Pageの Server scriptに対して「function showStarRating() {」の定義の直前に次のスクリプトを追加すればOKであった。

//a. data に kb_knowledge の u_order_of_sort のデータを追加
for (var i=0; i< data.items.length; i++) {
var kbnw = new GlideRecord("kb_knowledge");
kbnw.addQuery("sys_id", data.items[i].sys_id);
kbnw.query();
while (kbnw.next()) {
data.push("u_order_of_sort",kbnw.u_order_of_sort);
data.items[i].u_order_of_sort = kbnw.u_order_of_sort.getDisplayValue();
}
}
//b. data.items を u_order_of_sort で並べ替え
data.items.sort(function (a, b){
return a.u_order_of_sort.localeCompare(b.u_order_of_sort);
});

※ Client controller のスクリプトはデフォルトのままでOK。

参考になったのは、次の二つのコミュニティ。というかほぼこの合わせ技。
https://community.servicenow.com/community?id=community_question&sys_id=a8bfb26ddb58dbc01dcaf3231f96198f
https://community.servicenow.com/community?id=community_question&sys_id=2438061ddba91b047b337a9e0f961928

「a.」の部分ではデフォルトのスクリプトが作成したdata.itemsに並び順を指定するカラムをkb_knowledgeテーブルから探して追加している。
「b.」の部分は②でやった内容とほぼ同じで「a.」で追加したデータでdata.itemsをソートしている。できてみれば割とシンプルな内容であった。

結果次のように設定した文字列順にソートされて表示できるようになった。

※画面上各記事の右下にある「data=」で始まる文字列はデバッグ用に追加した表示。

1点だけ残る疑問点は上記の画面で表示しているCategoryにはdata=800だったり920だったりという記事も存在するのだが、それらが表示されずdata=950の記事が表示されている点。

1画面10記事までの表示がデフォルトだが、data=950すなわちこのカテゴリ内で一番最後に配置される記事が表示されて、それ以前の順番の記事が表示から落ちている。
↓の画面でShow More とすれば、

↓の様にすべての記事が正しい順序で表示される。


これも推測なので確実ではないが、どうもどこかで、Category内の一番後ろの記事は必ず表示するというようなロジックが入っているように見える。

謎は尽きないが、ひとまず任意の順番で指定した通りに記事を表示させるという基本的なところは完成したと思われ、本シリーズはいったん完了とする。

実務運用上では順番指定のデータがStringでよいのか?Integerの方が良いのか?すでに運用開始している場合、sys_id順で表示されている現状とどのように整合を取って移行するのか、等々検討が必要な事項はいろいろあると思われる。

最後にカスタマイズ後のServer scriptを残しておく。

// populate the 'data' variable if (input) data.category = input.category; else data.category = $sp.getParameter("kb_category"); var kbIds = $sp.getKnowledgeBases(); var kbs = kbIds.split(','); data.limit = parseInt(options.limit_article) || 10; if (input && input.new_limit) data.limit = input.new_limit; var kb_cat = new GlideRecord("kb_category"); data.categoryDisplay = gs.getMessage("Select a category"); data.items = []; data.categoryExists = false; if (kb_cat.get(data.category)) { data.categoryExists = true; data.categoryDisplay = kb_cat.getDisplayValue(); data.items = $sp.getKBCategoryArticleSummaries(data.category, data.limit + 1 , 250); } var diff = data.items.length - data.limit; if (diff <= 0) data.showMore = false; else { data.items.splice(data.limit); data.showMore = true; } data.show_msg = gs.getMessage("Showing {0} items", data.limit + ""); var kbId = $sp.getParameter('kb_id'); data.kbId = kbId; if (kbId) { var gr = new GlideRecord("kb_knowledge_base"); if (gr.get(kbId)) data.kbName = gr.getDisplayValue("title"); } data.kb_knowledge_page = $sp.getDisplayValue("kb_knowledge_page") || "kb_view"; data.breadcrumbs = [{label: data.categoryDisplay, url: '#'}]; if (kb_cat.parent_id) { var rec = kb_cat.parent_id.getRefRecord(); while (rec.getRecordClassName() == "kb_category") { if (kbId) data.breadcrumbs.unshift({label: rec.getDisplayValue(), url: '?id=kb_category&kb_category=' + rec.getUniqueValue() + '&kb_id='+ kbId}); else data.breadcrumbs.unshift({label: rec.getDisplayValue(), url: '?id=kb_category&kb_category=' + rec.getUniqueValue()}); rec = rec.parent_id.getRefRecord(); } } if (kbs && kbs.length > 1) { if (kbId) data.breadcrumbs.unshift({label: data.kbName, url: '?id=' + data.kb_knowledge_page + '&kb_id='+ kbId}); data.breadcrumbs.unshift({label: gs.getMessage("All Knowledge Bases"), url: '?id=' + data.kb_knowledge_page}); } else data.breadcrumbs.unshift({label: gs.getMessage("Knowledge Base"), url: '?id=' + data.kb_knowledge_page}); data.showStarRating = showStarRating(); //data に kb_knowledge の u_order_of_sort のデータを追加 for (var i=0; i< data.items.length; i++) { var kbnw = new GlideRecord("kb_knowledge"); kbnw.addQuery("sys_id", data.items[i].sys_id); kbnw.query(); while (kbnw.next()) { data.push("u_order_of_sort",kbnw.u_order_of_sort); data.items[i].u_order_of_sort = kbnw.u_order_of_sort.getDisplayValue(); } } //data.items を u_order_of_sort で並べ替え data.items.sort(function (a, b){ return a.u_order_of_sort.localeCompare(b.u_order_of_sort); }); function showStarRating() { if (options.show_star_rating == "Yes") return true; if (options.show_star_rating == "No") return false; // check gating property for all rating options if (gs.getProperty("glide.knowman.show_rating_options", "true") != "true") return false; // does user have the right role? if (!gs.hasRole(gs.getProperty("glide.knowman.show_rating_options.roles"))) return false; // check specific property for stars if (gs.getProperty("glide.knowman.show_star_rating", "true") != "true") return false; // does user have the right role? return gs.hasRole(gs.getProperty("glide.knowman.show_star_rating.roles")); }

0 件のコメント:

ウェブサイトのURLにおけるトレイリングスラッシュの解釈と有無による動作の違い

インターネットが現代社会におけるコミュニケーションの基盤となっている今日、ウェブサイトのURLはビジネスや個人ブランディングにとって重要な役割を果たしています。URLは単にウェブページへの経路を示すだけでなく、SEO(検索エンジン最適化)においても重要な要素です。この記事では、U...