Skip to content

拡張スクリプト・スタイルの条件指定とファイル単位の配信(改修案) ​

第1版作成 最終更新 (日本時間)
確認バージョン1.5.8.1

本体の標準機能ではありません

このページは本体を改修する場合の設計メモです。前提にした現行の実装は 1.5.8.1 です。

1.5.8.1 では、App_Data/Parameters/ExtendedScripts・ExtendedStyles に置いた .js / .css には適用条件を付けられず、全ページに効きます。また、条件に合うものを全部つないで 1 本のファイルとして配信します。ここでは、同じ名前の JSON を横に置くと条件を指定でき、条件付きのものはファイルごとに配信する改修をまとめます。

現行の実装 ​

拡張機能ごとのファイル構成 ​

拡張機能は「JSON(メタデータ)を持つか」で 2 種類に分かれます。

拡張機能ファイルJSON本体を別ファイルに置く条件指定
ExtendedScripts.jsなし—不可(全ページ)
ExtendedStyles.cssなし—不可(全ページ)
ExtendedHtmls.htmlなし—不可(ファイル名の _ja などで言語だけ)
ExtendedServerScripts.jsonあり.json.js(あれば Body を上書き)可
ExtendedSqls.jsonあり.json.sql(あれば CommandText を上書き)可
ExtendedPlugins.jsonありなし(LibraryPath で DLL を指定)可
ExtendedNavigationMenus.jsonありなし可
ExtendedFields.jsonありなし可

.js / .css を読み込む Initializer.ExtendedScripts() / ExtendedStyles() は、ファイル名の昇順(サブフォルダは再帰)に Name・Path・Script(Style)だけを設定します。SiteIdList などの条件は空のままなので、ExtensionWhere で「条件なし」と判定されて全ページに効きます。詳しくは 拡張スクリプトの仕組み と 拡張スタイルの仕組み を参照してください。なお Extensions テーブルに登録した拡張スクリプト・スタイルには条件を付けられます(Extensions テーブルで拡張機能を DB 管理)。

条件の判定(ExtensionWhere) ​

どの拡張機能も ExtendedBase を継承し、ExtensionUtilities.ExtensionWhere<T>() で絞り込まれます(ExtensionUtilities.cs)。

プロパティ型意味
SiteIdList / IdListList<long>サイト ID / レコード ID
DeptIdList / GroupIdList / UserIdListList<int>組織 / グループ / ユーザー
Controllers / ActionsList<string>コントローラ名 / アクション名
ColumnListList<string>項目名(項目拡張 HTML など)
Disabledbooltrue で無効
SpecifyByNamebooltrue なら Name が一致したときだけ

リストが空なら条件なし、値があれば一致したときだけ、先頭に - を付けた値は「それ以外」です。

配信の流れ ​

図を読み込み中…

この方式には次の問題があります。

問題内容
キャッシュ1 ファイル変えるだけで v が変わり、関係ないスクリプトも取り直しになる
デバッグブラウザの開発者ツールで、どのファイルのコードかが分かりにくい
順序ファイル名の昇順でつながるので、依存関係のある順序はファイル名で調整するしかない

改修案 ​

1. .js.json / .css.json で条件を指定する ​

.js / .css と同じ名前に .json を付けたファイル(コンパニオンファイル)を置き、そこから条件だけを読み込みます。

text
App_Data/Parameters/ExtendedScripts/
├── my-script.js           ← スクリプト本体(今までどおり)
└── my-script.js.json      ← 条件(新規)
json
{
    "SiteIdList": [100, 200],
    "Controllers": ["items"],
    "Actions": ["edit", "new"],
    "Disabled": false
}

Initializer.ExtendedScripts() の .js のループで、file.FullName + ".json" があれば ExtendedScript としてデシリアライズし、SiteIdList・IdList・DeptIdList・GroupIdList・UserIdList・Controllers・Actions・Disabled・Description を読み込んだ要素に写します。ExtendedStyles() も同じです。条件のプロパティは ExtendedBase にあるので、ExtendedScript / ExtendedStyle のクラスにプロパティを足す必要はありません。

*.js だけを列挙しているので、.js.json がスクリプトとして読まれることはありません。拡張 HTML にも name_ja.html.json のように同じ考え方を当てはめられます。

2. 条件付きのものはファイルごとに配信する ​

コンパニオンファイルを持つスクリプトは 1 つずつ <script> タグにし、/resources/scripts?name=ファイル名&v=そのファイルのハッシュ で返します。フォルダ構成を URL に出さないよう、パスではなく Name で識別します。

図を読み込み中…

ResourcesController.Scripts に name を受け取らせ、空なら今までどおり JavaScripts.Get、あれば新しく作る JavaScripts.GetByName(context, name) を呼びます。GetByName でも ExtensionWhere で条件を確かめ、条件に合わない名前を指定されたら返さないようにします。スタイル(Styles・Css・HtmlStyles)も同じ形にします。

3. 互換性 ​

置いたファイル動作
.js だけ今までどおり(つないで配信・全ページ)
.js と .js.jsonJSON の条件で絞り、ファイルごとに配信

コンパニオンファイルを置かない限り今の動作は変わらないので、既存環境への影響はありません。

改修箇所 ​

ファイル内容
Implem.DefinitionAccessor/Initializer.csExtendedScripts()・ExtendedStyles() でコンパニオンファイルを読む
Implem.Pleasanter/Libraries/HtmlParts/HtmlScripts.csコンパニオンファイルのあるものを個別の <script> で出す
Implem.Pleasanter/Libraries/HtmlParts/HtmlStyles.cs同じく個別の <link> で出す
Implem.Pleasanter/Libraries/Resources/JavaScripts.csGetByName(context, name) を足す
Implem.Pleasanter/Libraries/Resources/Css.csGetByName(context, name) を足す
Implem.Pleasanter/Controllers/ResourcesController.csScripts / Styles に name パラメータを足す

関連ページ ​

変更履歴

第1版拡張ライブラリの読み込みと開発・デバッグ、拡張ヘッドリンク、SMTP の OAuth 送信の解説と、多言語・外部公開カレンダー・スレッド型サイトなどの改修・設計メモを追加