1725802530
2024-09-04 08:25:21
1. 空のCMSアプリケーションを作成する
まず、空の CMS アプリケーションをセットアップしましょう。
Visual Studio の NuGet パッケージ マネージャーまたはコマンド ラインを使用して、ソリューションに NuGet パッケージをインストールします。
dotnet add package EPiServer.CMS
2. ヘッドレスOptimizely Forms APIをセットアップする
Optimizely Headless Form APIは、1つのメインNuGetパッケージで構成されています。 Optimizely.Cms.Forms.Serviceまた、いくつかの追加の NuGet パッケージを使用すると、必要な機能のみをインストールできます。
Visual Studio の NuGet パッケージ マネージャーまたはコマンド ラインを使用して、ソリューションに NuGet パッケージをインストールします。
dotnet add package Optimizely.Cms.Forms.Service
フォームのヘッドレスAPIオプションを構成する
startup.cs の ConfigureServices で API を構成します。
services.AddOptimizelyFormsService(options => {
options.EnableOpenApiDocumentation = true;
options.FormCorsPolicy = new FormCorsPolicy {
AllowOrigins = new string[] {
"*"
}, //Enter '*' to allow any origins, multiple origins separate by comma
AllowCredentials = true
};
options.OpenIDConnectClients.Add(new() {
Authority = "" //Enter the client's domain that needs authentication.
});
});
3. OpenIDConnectを使用した認証
インストール Episerver.OpenIDConnect Visual Studio の NuGet パッケージ マネージャーまたはコマンド ラインを使用してパッケージを作成します。
dotnet add package Episerver.OpenIDConnect.UI
OpenIDConnect の暗号化キーを設定します。
public class FormServiceOptionsPostConfigure : IPostConfigureOptions
{
private readonly OpenIddictServerOptions _options;
public FormServiceOptionsPostConfigure(IOptions
{
_options = options.Value;
}
public void PostConfigure(string name, OptimizelyFormsServiceOptions options)
{
foreach (var client in options.OpenIDConnectClients)
{
foreach (var key in _options.EncryptionCredentials.Select(c => c.Key))
{
client.EncryptionKeys.Add(key);
}
foreach (var key in _options.SigningCredentials.Select(c => c.Key))
{
client.SigningKeys.Add(key);
}
}
}
}
Startup.cs で OpenIdConnect を構成します。
services.AddOpenIDConnect
useDevelopmentCertificate: true,
signingCertificate: null,
encryptionCertificate: null,
createSchema: true
);
services.AddOpenIDConnectUI();
services.TryAddEnumerable(ServiceDescriptor.Singleton
4. OIDC UIを使用してキー/シークレットを作成し、認証をテストする
設定の「OpenID Connect」タブを開き、新しいアプリケーションを作成してクライアントIDとクライアントシークレットを入力します。
Postman で次のパラメータを使用して /api/episerver/connect/token に POST リクエストを送信し、すべてが機能するかどうかをテストします。
- クライアントID: APIクライアント
- クライアントシークレット: スーパーシークレット
- 許可タイプ: クライアント資格情報
期間限定のアクセストークンを受け取ります。

5. API仕様
ホスト サイトでは次のエンドポイントが利用可能である必要があります。
- GET – /_forms/v1/forms/{ContentKey}?language={Language} – コンテンツキーでフォーム要素を含むフォームデータを取得します
- PUT – /_forms/v1/forms/ – フォームを送信します。
API が正しく動作していることを確認するには、ブラウザでフォーム ヘッドレス API を開きます。
http://
注: ContentKeyはハイフンなしのコンテンツGUID IDです
API の詳細については、以下をご覧ください。 ヘッドレスフォーム API 仕様
6. 単一のテキスト入力でシンプルなHello Worldフォームを作成する
右側のメニュー パネルで、新しいフォームを作成し、フォーム名を入力します。

フォームにテキストボックスと送信ボタンを追加して、フォームを公開します。

7. Postmanを使用してフォームを取得する
ポストマンコレクションをインポートする ヘッドレス Sample.postman_collection.json
8. フォームレンダリング用のバックエンドサイトを準備する
8.1. 両方のケースでウェブサイト管理設定を更新する
- サイトを閲覧する > ウェブサイトの管理: アップデート 配送場所 = ローカルホスト:3000
- サイトを閲覧する > ウェブサイトの管理 : 取り除く ホスト名 = * リスト
- (オプション) ManagementSiteを更新して、httpsではなくhttpを使用するようにします。 json (サイトをローカルにデプロイする場合): “applicationUrl”: “http://ローカルホスト:8000“、
- React サイトを参照:http://localhost:3000/en/[pageURL]
8.2. ContentGraph を使用してフォームをレンダリングする
インストール Optimizely.ContentGraph.Cms そして Optimizely.Cms.Forms.ContentGraph Visual Studio の NuGet パッケージ マネージャーを使用するか、コマンド ラインを使用します。
dotnet add package Optimizely.ContentGraph.Cms
dotnet add package Optimizely.Cms.Forms.ContentGraph
- CGキーを追加
appsettings.json(同じレベルでEpiserver)。
"Optimizely": {
"ContentGraph": {
"GatewayAddress": ">",
"AppKey": ">",
"Secret": ">",
"SingleKey": ">",
"AllowSendingLog": true,
"ContentVersionSyncMode": "DraftAndPublishedOnly",
"Include": {
"ContentIds": [],
"ContentTypes": []
},
"SyncReferencingContents": true
}
}
- 設定を追加する
Startup.cs。
//Register ContentGraph for HeadlessForm
services.AddContentDeliveryApi(op => {
op.DisableScopeValidation = true;
op.RequiredRole = null;
});
services.ConfigureContentApiOptions(o => {
o.FlattenPropertyModel = true;
o.IncludeNumericContentIdentifier = true;
});
services.AddContentGraph();
services.AddOptimizelyFormsContentGraph();
8.3. Rest APIを使用してフォームをレンダリングする
追加 ReactController.cs ファイル Controllers ページ内のすべてのフォームキーを取得するフォルダ
using EPiServer;using EPiServer.Core;using EPiServer.Forms.Implementation.Elements;using EPiServer.ServiceLocation;using EPiServer.SpecializedProperties;using EPiServer.Web;using EPiServer.Web.Routing;using Microsoft.AspNetCore.Mvc;using System.Collections.Generic;using System.Threading;using System.Threading.Tasks;
namespace AlloyMvcTemplates.Controllers;[Route("api/[controller]")][ApiController]public class ReactController : ControllerBase{ public ReactController() { }
[HttpGet("GetFormInPageByUrl")] public async Task { var builder = new EPiServer.UrlBuilder(url); var content = UrlResolver.Current.Route(builder, ContextMode.Default);
if (content is null) { return NoContent(); } CancellationTokenSource source = new CancellationTokenSource(); CancellationToken token = source.Token;
var contentLoader = ServiceLocator.Current.GetInstance
var pageContent = contentLoader.Get
var pageModel = new PageModel();
if (pageContent is not null) { pageModel.Title = pageContent.Name; pageModel.PageUrl = UrlResolver.Current.GetUrl(content.ContentLink);
if (pageContent.Property.Keys.Contains("MainContentArea")) { var contentArea = pageContent.Property["MainContentArea"] as PropertyContentArea; foreach (var item in contentArea.PublicContentArea.FilteredItems) { var contentItem = contentLoader.Get
if(contentItem is FormContainerBlock) { pageModel.FormKeys.Add(contentItem.ContentGuid.ToString("N")); } } } }
return Ok(pageModel); }}
public class PageModel{ public string Title { get; set; } public string PageUrl { get; set; } public List}
9. シンプルなReactアプリを使用してフォームをレンダリングする
9.1. Reactアプリテンプレートを作成する
- 空のフォルダを作成します: クライアントアプリ 例えば
- フォルダーでcmdを実行します:
npx create-react-app headless-form --template typescript
結果: ヘッドレスフォーム フォルダが追加されました
9.2. JS SDKをインストールする
- 移動 ヘッドレスフォーム
- ファイルを作成する .npmrc 内容:
@episerver:registry=https://pkgs.dev.azure.com/EpiserverEngineering/netCore/_packaging/HeadlessForms/npm/registry
9.3. 両方のケースの内容を含む.envファイルを追加する
REACT_APP_ENDPOINT_GET_FORM_BY_PAGE_URL=https://localhost:8000/api/React/GetFormInPageByUrl?url=
REACT_APP_HEADLESS_FORM_BASE_URL=https://localhost:8000/
REACT_APP_AUTH_BASEURL=https://localhost:8000/api/episerver/connect/token
コンテンツグラフを使用してフォームをレンダリングするには、以下の行を.envファイルに追加します。
REACT_APP_CG_PREVIEW_URL={GatewayAddress}/content/v2
REACT_APP_CONTENT_GRAPH_GATEWAY_URL={GatewayAddress}/content/v2?auth={SingleKey}
REACT_APP_LOGIN_CLIENT_ID=frontend
REACT_APP_HEADLESS_FORM_BASE_URL=https://localhost:8000/
注記:
- 必要に応じてポート = ManagementSiteのURLを更新します
- GatewayAddress、SingleKeyはappsetting.jsonから取得されます。
9.4. ファイルを追加する srcuseFetch.ts フォームデータを要求する関数を含む
import { useEffect, useState } from "react";
export const useFetch = (url: string) => {
const [data, setData]= useState
const [loading, setLoading] = useState
const [error, setError] = useState
useEffect(()=>{
const fetchData = async () => {
setLoading(true);
fetch(url)
.then(async (response: Response)=>{
if(response.ok){
setData(await response.json());
}
})
.catch((err: any)=>{
setError(err);
})
.finally(()=>{
setLoading(false);
});
};
if(!loading){
fetchData();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
},[url]);
return {data, loading, error};
}
9.5. srcApp.tsx を更新する
import './App.css';
import { useFetch } from './useFetch';
import { Form, FormLogin } from '@episerver/forms-react';
import { FormCache, FormConstants, IdentityInfo, extractParams } from '@episerver/forms-sdk';
import { useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
function App() {
const location = useLocation();
const { language } = extractParams(window.location.pathname)
const url = `${process.env.REACT_APP_ENDPOINT_GET_FORM_BY_PAGE_URL}${location.pathname}`;
const { data: pageData, loading } = useFetch(url);
const formCache = new FormCache();
const [identityInfo, setIdentityInfo] = useState
accessToken: formCache.get
} as IdentityInfo);
const history = useHistory()
const handleAuthen = (identityInfo: IdentityInfo) => {
setIdentityInfo(identityInfo);
}
return (
Hello
{loading &&
Loading...
}
{!loading && pageData && (
{pageData.formKeys.map((key: any) => (
key={key}
formKey={key}
language={language ?? "en"}
baseUrl={process.env.REACT_APP_HEADLESS_FORM_BASE_URL ?? "http://world.optimizely.com/"}
identityInfo={identityInfo}
history={history}
currentPageUrl={pageData.pageUrl}
// optiGraphUrl={process.env.REACT_APP_CONTENT_GRAPH_GATEWAY_URL}//uncomment this line if you want to render using content graph
/>
))}
Login
clientId='TestClient'
authBaseUrl={process.env.REACT_APP_AUTH_BASEURL ?? ""}
onAuthenticated={handleAuthen} />
>
)}
);
}
export default App;
2024年9月4日
#Optimizely #ヘッドレス #フォームのセットアップ #Optimizely #開発者コミュニティ