今、Umbraco 13 はセキュリティアップデートだけを受けられるので、アップデートする時間だ!
次の「LTS」バージョンは Umbraco 17。僕は「LTS」バージョンだけをアップデートしたいので、僕の Umbraco パッケージ Auto dictionaries を Umbraco 17 にアップデートする。
第1回はここでもっと読めるが、この記事だけでも内容は理解できる。
先に、「Visual Studio 2026」にアップデートして、Webプロジェクトを Umbraco 17にアップデートした。
今回はプロジェクトの構造を変えて、フロントエンドのコードを「AngularJS」から「TypeScript」に変える。
僕はたいていバックエンドのコードで働いているので、バックエンドのコードのほうがいい。
だから、今回はバックエンドのコードを直し始めたいけど、ほかのプロジェクトを働いた時、
多くのバックエンドのコードが使えなかった。
そのため、フロントエンドのコードを「AngularJS」から「TypeScript」に変え始めたほうがいい。
今、僕の予定は
これからは「TypeScript」を使うため、「TypeScript」のソースコードとコンパイル後のコードは同じフォルダに置かない。
コンパイル後のコードはwwwrootに出力するので、「TypeScript」のコードは別のフォルダが必要だ。
このブログでケビン・ジャンップを見つけた。
「Early Adopter's guide to Umbraco v14 - Package structure」
このブログ記事によると、ケビンはこのパッケージの構造を使っている。
+ -- <package>.sln
+ -- <package>.csproj
+ -- <package>.Client.csproj
+ -- <package>.Core.csproj
+ -- <package>.Site.csprojこのパッケージの構造を見始めた。その構造はとてもよさそうだから、僕も使いたい。でも、よく見た時、ちょっと問題を見つけた。
ケビンはフロントエンドのコードのために、自分の「NuGet」のパッケージがある。
それはほしくない。だから、ほかの方法を使う。
「Auto dictionaries」のプロジェクトの中で、「Client」のフォルダを作ったと、その中で、フロントエンドのコードを置く。
たいてい僕はCMDでフロントエンドのコードをビルドすると、Visual Studioでバックエンドのコードをビルドする。それはとても大変だった。
でも!ケビンの他のブログは「An Umbraco v14 Early Adopter's Development setup」を見つけた!
そのブログ記事に、ケビンはてんさいな解決策を書いた!
ケビンの解決策は全部でVisual Studioができる!
「Task Runner Explorer」といえ、Visual Studioの拡張機能はフロントエンドコードコンパイルを使える。

その拡張機能を使いたい時、プロジェクトのルートでがpackage.jsonある。
だから、ネスト構造を使わない。
でも、ルートの中で、package.json を作った。

そして、これで書いた
{
"name": "auto-dictionaries",
"private": true,
"version": "17.0.0",
"scripts": {
"install-client": "cd ./AutoDictionaries/Client/ && npm install",
"build-watch": "cd ./AutoDictionaries/Client/ && npm run watch"
},
"keywords": [],
"author": "",
"license": "ISC"
}このファイルの一番大切はcd ./AutoDictionaries/Client/だ
これから、Visual Studioでビルド&ウォッチのコードができる。

この解決策はとても気に入っている!
3ステップは終わった!次に、一番難しい問題を解決しようと思う。
まず「Vite」をインストールする
npm create vite@latest「TypeScript」と「Lit」を選ぶ。
それは既定構造を受けたと、そのパスはAutoDictionaries/Client。
今、2つの方ができる。
AutoDictionaries/Client/public/umbraco-package.jsonにはすべて登録するか、「backofficeEntryPoint」だけ登録すると、AutoDictionaries/Client/src/index.tsには他のを登録。たくさんことを登録するから、AutoDictionaries/Client/public/umbraco-package.jsonの解決策を使った特、そのファイルは長くすぎると思うから、index.tsの解決策を使おうと思ういる。
import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api';
import { manifests } from './manifests.js';
export * from './components/index.js';
export const onInit: UmbEntryPointOnInit = (_host, extensionRegistry) => {
extensionRegistry.registerMany(manifests);
};APIのリクエストをしたいなら、「Bearer token」を追加しないと。「UMB_AUTH_CONTEXT 」を使える。
型付きAPIを受けたいから、「Hey API」のnpmのパッケージを使う。
「Hey API」を使うために、Swaggerを実装したほうがいい。
だから、早いSwaggerの実装をする。
namespace AutoDictionaries.Composers
{
internal class ConfigureSwaggerGenOptions : IConfigureOptions<SwaggerGenOptions>
{
public void Configure(SwaggerGenOptions options)
{
options.SwaggerDoc(
"autoDictionaries",
new OpenApiInfo
{
Title = "Auto Dictionaries Management Api",
Version = "Latest"
});
options.CustomOperationIds(e => $"{e.ActionDescriptor.RouteValues["action"]}");
}
}
}とテスト用のコントローラー を作る
namespace AutoDictionaries.Controllers
{
[ApiController]
[ApiVersion("1.0")]
[MapToApi("autoDictionaries")]
[ApiExplorerSettings(GroupName = "autoDictionaries")]
[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]
public class AutoDictionariesApiController : Controller
{
[HttpGet("get-all-views")]
public string GetAllViews() => string.Empty;
}
}次に、openapi-ts.config.tsを作る。
import { defineConfig } from '@hey-api/openapi-ts';
export default defineConfig({
input: 'https://localhost:44360/umbraco/swagger/autoDictionaries/swagger.json',
output: {
path: 'src/api',
},
plugins: [
{
name: '@hey-api/sdk',
asClass: true,
classNameBuilder: '{{name}}Service',
},
],
});自己署名証明書の問題があるから、「cross-env」のnpmのパッケージをインストールする
今は、プロジェクトを起動してからこのコマンドを実行し、型付きAPIを作る。
cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 openapi-ts
index.ts「Bearer token」を追加する
export const onInit: UmbEntryPointOnInit = (_host, extensionRegistry) => {
extensionRegistry.registerMany(manifests);
host.consumeContext(UMBAUTH_CONTEXT, (_auth) => {
if (!_auth) return;
var config = _auth.getOpenApiConfiguration();
client.setConfig({
auth: config.token,
baseUrl: config.base,
credentials: config.credentials,
});
client.interceptors.request.use(async (request, _options) => {
const token = await _auth.getLatestToken();
request.headers.set('Authorization', `Bearer ${token}`);
return request;
});
});
};今、APIのリクエストができる!
では、今は、新しいツリーを作った。これは正直かなり大変だった。多くの時間がかかったので、あとで自分の記事として書こうと思っている。
後で、いろんなことを変えた。
たとえば、先に、IDを使ったけど、今は、GUIDを使った。
先は、これはディクショナリのアイテムのパス。
/umbraco#/translation/dictionary/edit/11でも今は、これになった。
/umbraco/section/translation/workspace/dictionary/edit/62cbe7af-2ff1-4584-b2e2-6f50cf11e116それに、Umbracoでは「Infinite Editor」の名前を変えた。今の名前は「Sidebar」だ。
先は、「Infinite Editor」を使った。
vm.generateDictionaries.editor = {
view: "/App_Plugins/AutoDictionaries/backoffice/infiniteEditors/generateDictionaries.html",
title: "Generate dictionaries",
size: "medium",
selectedContent: vm.selectedContent,
autoDictionariesModel: vm.view,
allowTranslate: vm.allowTranslate,
submit: function () {
editorService.close();
$route.reload();
},
close: function () {
editorService.close();
}
};
editorService.open(vm.generateDictionaries.editor)
でも今は、先ずは「UmbModalToken」を使った。
import { UmbModalToken } from "@umbraco-cms/backoffice/modal";
import { PreviewAddNewDictionaryItemToViewDto } from "../api";
export const GENERATE_DICTIONARY_MODAL_TOKEN = new UmbModalToken<PreviewAddNewDictionaryItemToViewDto, string[]>('autoDictionaries.generateDictionaries.modal', {
modal: {
type: 'sidebar',
size: 'medium'
}
});そしてコンストラクタで 「Context API」 を使って、コンテキストを消費する
constructor() {
super();
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (_instance) => {
this._modalContext = _instance;
});
}最終に、これで開ける。
async #openCreateDictionaryModal() {
const modalContext = await this._modalContext?.open(this, GENERATE_DICTIONARY_MODAL_TOKEN, {
data: {
staticContent: this._selectedContent,
autoDictionariesModel: this._item,
canTranslate: this._translationSetting
} as PreviewAddNewDictionaryItemToViewDto
});
await modalContext?.onSubmit();
}それは、比較的目立つ変更だと思う。
このステップはよくUmbraco 17のドキュメントで解決策と正しく使う「UUI Component」をさがしていたと。
でも、今までに、あまりドキュメントがないために、よく他のUmbraco 17のパッケージやブログやUmbraco 17のソースコードなどを見た。
それは一番大切だと思う。
4ステップはもうやっと終わった!
このステップはやっと終わった!
今回はたくさんことをした。新しいプロジェクトの構造がある。
「Task Runner Explorer」を使えた、嬉しくなった!
あまり「TypeScript」も使わなかったと。そのために、これはめちゃ難しかったと思う。
ケビン・ジャンップのブログは本当に大きな助け!
もうすぐパッケージをリリースできる!
最終はバックエンドのコードを直す!

ヨハネス・ランツ
ウェブ開発者・経験8年