日本語版
最新ニュース
企業

Optimizely ヘッドレス フォームのセットアップ | Optimizely 開発者コミュニティ

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 パッケージをインストールします。…

Optimizely ヘッドレス フォームのセットアップ | Optimizely 開発者コミュニティ

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 = 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, FormServiceOptionsPostConfigure>());

    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:///_フォーム/v1/フォーム/?言語=英語

    注: 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 GetFormInPageByUrl(string url)
        {
            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(content.ContentGuid);

            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(item.ContentLink);

                        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 FormKeys { get; set; } = new 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(null);

        const [loading, setLoading] = useState(false);

        const [error, setError] = useState(null);

        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(FormConstants.FormAccessToken)

        } 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 #開発者コミュニティ

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。