ヘッドレスのOracle Content Managementを使用したFlutterで最小限のサイトを構築
イントロダクション
Flutterは、Googleによるオープン・ソース・フレームワークで、ネイティブにコンパイルされた、単一コードベースからのマルチプラットフォーム・アプリケーションを構築します。Flutterコードは、任意のデバイスで高速パフォーマンスを実現するために、ARMまたはIntelマシン・コードおよびJavaScriptにコンパイルされます。Flutterは、Oracle Content Managementからコンテンツを消費するアプリケーションを構築するための強力なツールです。適切なコンテンツ・モデルを使用して、典型的なブログを構成するFlutter UIを迅速に構築できます。
このチュートリアルでは、Oracle Content ManagementをヘッドレスCMSとして活用することで、Flutterでシンプルな最小限のサイトを構築します。このFlutterサンプルは、GitHubで入手できます。
このチュートリアルは、次の3つのステップで構成されています。
前提条件
このチュートリアルに進む前に、最初に次の情報を読むことをお薦めします。
このチュートリアルに従うには、次のものが必要です。
- Oracle Content Managementのサブスクリプション
- コンテンツ管理者ロールを持つOracle Content Managementアカウント
- ノード・バージョン10以上のWindowsまたはMacコンピュータ
構築内容
Flutterが最小限の場合は、イメージおよびその他のコンテンツをOracle Content Managementリポジトリから簡単に取得できます。
ビルドする内容を確認するには、Oracle Content Managementのコンテンツを使用する基本的なFlutter最小サイトであるチュートリアルの終了状態を次に示します。
ホーム画面はこのチュートリアルの最後に表示されます。
このチュートリアルの最後には、「contact us」画面は次のようになります。
続行するには、Oracle Content Managementへのアクティブなサブスクリプションがあり、コンテンツ管理者ロールでログインする必要があります。
タスク1: Oracle Content Managementの準備
Oracle Content Managementインスタンスがまだない場合は、クイック・スタートを参照して、Oracle Cloudに登録する方法、Oracle Content Managementインスタンスのプロビジョニング方法、およびOracle Content ManagementをヘッドレスCMSとして構成する方法を学習します。
このチュートリアルでは、コンテンツ・モデルを作成する必要があります。使用可能なダウンロード可能なアセット・パックがあり、コンテンツ・タイプおよび関連するコンテンツで空のリポジトリを埋めます。
Oracle Content Managementを準備するには:
チャネルおよびアセット・リポジトリの作成
コンテンツを公開するには、まずOracle Content Managementでチャネルおよびアセット・リポジトリを作成する必要があります。
Oracle Content Managementでチャネルおよびアセット・リポジトリを作成するには:
Oracle Content Management Webインタフェースに管理者としてログインします。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「チャネルの公開」を選択します。
右上隅にある「Create」をクリックして、新しいチャネルを作成します。このチュートリアルの目的でチャネルにOCEMinimalChannelという名前を付け、アクセスをパブリックにしておきます。「保存」をクリックしてチャネルを作成します。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。
右上隅にある「作成」をクリックして、新しいアセット・リポジトリを作成します。このチュートリアルでは、アセット・リポジトリにOCEMinimalRepositoryという名前を付けます。
「公開チャネル」フィールドで、OCEMinimalChannelチャネルを選択して、OCEMinimalRepositoryリポジトリ内のコンテンツをOCEMinimalChannelチャネルに公開できることをOracle Content Managementに示します。終了したら、「Save」をクリックします。
Oracle Content Managementサンプル資産パックのインポート
このチュートリアルに必要なすべてのコンテンツ・タイプおよびアセットを含む、事前構成されたOracle Content Managementサンプル・アセット・パックをダウンロードできます。
このチュートリアルで使用するコンテンツのコピーは、Oracle Content Management Samples Asset Packからアップロードできます。これにより、コンテンツ・タイプを試して内容を変更できます。Oracle Content Management Samples Asset Packをインポートする場合は、アセット・パック・アーカイブOCESamplesAssetPack.zipをダウンロードし、選択したディレクトリに抽出できます。
Oracle Content Managementのダウンロード・ページからOracle Content Management Samples Asset Pack (OCESamplesAssetPack.zip)をダウンロードします。ダウンロードしたzipファイルをコンピュータ上の場所に抽出します。抽出後、この場所にはOCEMinimal_data.zipというファイルが含まれます。
Oracle Content Management Webインタフェースに管理者としてログインします。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。次に、OCEMinimalRepositoryを選択し、上部アクション・バーの「コンテンツのインポート」ボタンをクリックします。
OCEMinimal_data.zipをローカル・コンピュータから「ドキュメント」フォルダにアップロードします。
アップロードしたら、OCEMinimal_data.zipを選択し、「OK」をクリックしてコンテンツをアセット・リポジトリにインポートします。
コンテンツが正常にインポートされたら、「アセット」ページに移動し、OCEMinimalRepositoryリポジトリを開きます。すべての関連イメージおよびコンテンツ項目がアセット・リポジトリに追加されたことがわかります。
左上の「すべて選択」をクリックし、「公開」をクリックして、以前に作成した公開チャネル(OCEMinimalChannel)にインポートされたすべてのアセットを追加します。
公開する前に、すべての資産を検証する必要があります。最初に、選択したチャネルとしてOCEMinimalChannelを追加し、「検証」ボタンをクリックします。
アセットの検証後、右上隅にある「公開」ボタンをクリックして、選択したチャネルにすべてのアセットを公開できます。
完了すると、すべてのアセットが公開された「アセット」ページが表示されます。(アセット名の上にあるアイコンで確認できます。)
タスク2: Flutterでの最小サイトの作成
FlutterアプリケーションでOracle Content Managementコンテンツを消費するには、GitHubでオープン・ソース・リポジトリとして使用できるFlutter最小サイト・サンプルを使用します。
ノート: Flutterサンプルの使用はオプションであり、このチュートリアルで使用してすぐに開始することに注意してください。独自のFlutterアプリケーションを作成することもできます。
Flutterでの最小サイトの作成は、次のステップで構成されます。
- Flutterのインストール
- サンプル・リポジトリのクローニングと依存関係のインストール
- Flutterアプリケーションの構成
- Oracle Content Management REST APIを使用したコンテンツのフェッチ
Flutterのインストール
Flutterを初めて使用する場合は、環境を設定します。それを設定する手順は、FlutterのWebサイトにあります。オペレーティング・システムに対応するオプションを使用します。インストール手順のサマリーを次に示します。
- Flutter SDKを入手しましょう。
- パス環境変数を更新します。
flutter doctor
を実行します。- FlutterのWebサイトで説明されているステップに従って、選択したエディタをインストールします。
- Android Studio、IntelliJ、VSコードまたはEmacsのエディタ・プラグインを追加します。手順では、エディタにFlutterおよびDartプラグインをインストールする方法を指定します。
- 適切な場所、sdkおよびkotlinバージョンを参照するように、android.propertiesファイルの値を変更します。また、適切なバージョンのandroid.gradleファイルの値を変更する必要もあります。
サンプルリポジトリのクローニングと依存関係のインストール
Flutter最小サイト・サンプルは、GitHubでオープンソース・リポジトリとして使用できます。
まず、GitHubからローカル・コンピュータにサンプルをクローニングし、ディレクトリをリポジトリ・ルートに変更する必要があります:
git clone https://github.com/oracle-samples/oce-flutter-minimal-sample.git
cd oce-flutter-minimal-sample
Android Studioまたはその他の任意のエディタからプロジェクトを開きます。プロジェクトで使用されているすべてのパッケージを取得するには、「パッケージの取得」ボタンをクリックします。
Flutterアプリケーションの構成
このFlutterの最小サンプルでは、REST APIリクエストが適切なインスタンスURLおよびAPIバージョンを正しいチャネル・トークンでターゲットにできるように、いくつかの情報を構成する必要があります。lib/config/oce.dartで定義されたこれらの値は、REST APIのエンドポイントを確立するためにlib/networking/content.dartで定義された関数で使用されます。
lib/config/oce.dartに次の情報が表示されます。
const Map<String, String> config = <String, String>{
'serverUrl': 'https://samples.mycontentdemo.com',
'apiVersion': 'v1.1',
'channelToken': 'ba0efff9c021422cb134c2fd5daf6015'
};
各キーと値のペアを、インスタンスURL、ターゲットにするAPIバージョンおよび公開チャネルに関連付けられたチャネル・トークンを反映するように変更します。このチュートリアルのチャネルはOCEMinimalChannelです。
また、アプリケーション全体で使用するイメージも構成する必要があります。同じファイルに次の内容が表示されます。
const Map<String, String> appConfig = <String, String>{
'homePage': 'Banner1.jpg',
'contactUs' : 'Banner2.jpg',
'logo' : 'Logo.png',
'footerLogo' : 'Powered_by_OCE.png',
};
インスタンスの値を反映するように各イメージの名前を変更します。
Oracle Content Management REST APIを使用したコンテンツのフェッチ
コンテンツ配信用のREST APIでは、Oracle Content Managementで公開されたアセットにアクセスできます。公開済アセットには、コンテンツ・アイテムやデジタル・アセット、およびそれらのレンディションが含まれます。これで、Oracle Content Management REST APIを使用してコンテンツをフェッチし、最小のFlutterアプリケーションでレンダリングできるようになりました。
lib/networking/content.dartファイルには、REST APIを使用してoce.dartファイルに指定されたサーバーに接続し、そこからレスポンスを返すメソッドがあります。
//Utility method to build up the URL for published content.
String _getPublishedContentServerURL() {
final String? serverUrl = data['serverUrl'] as String?;
final String? apiVersion = data['apiVersion'] as String?;
return '$serverUrl/content/published/api/$apiVersion/';
}
// Adds the channel token to the URL
String _addChannelToURL(String currUrl) {
final String? channelToken = data['channelToken'] as String?;
return '$currUrl?channelToken=$channelToken';
}
//Make an http get call and return the response if successful
Future<dynamic> _get(String url) async {
dynamic responseJson;
try {
final Response response = await get(Uri.parse(url));
responseJson = _returnResponse(response);
} on SocketException {
throw FetchDataException(kConnectionError);
}
return responseJson;
}
//Return the json decoded response body if response status is successful
dynamic _returnResponse(Response response) {
switch (response.statusCode) {
case 200:
final Map<String, dynamic>? responseJson =
json.decode(response.body.toString()) as Map<String, dynamic>?;
return responseJson;
case 400:
throw BadRequestException(response.body.toString());
case 401:
case 403:
throw UnauthorizedException(response.body.toString());
case 500:
default:
throw FetchDataException('StatusCode : ${response.statusCode}');
}
}
イメージをレンダリングする場合、content.dartには、アセットの様々なレンディションを取得するためのヘルパー・メソッドも用意されています。
String getMediumRenditionUrl(Map<String, String> args) {
final String itemId = args['id'];
if (itemId == null) return null;
String url = _getPublishedContentServerURL();
url = '${url}assets/$itemId/Medium';
// add the channel token to the URL
url = _addChannelToURL(url);
url = '$url&format=jpg&&type=responsiveimage';
return url;
}
String getRenditionURL(Map<String, String> args) {
final String itemId = args['id'];
if (itemId == null) return null;
String url = _getPublishedContentServerURL();
url = '${url}assets/$itemId/native';
// add the channel token to the URL
url = _addChannelToURL(url);
return url;
}
lib/networking/services.dartファイルには、アプリケーションのデータを取得するためのすべてのコードが含まれています。
イメージ・データのフェッチ中
lib/networking/services.dartを開き、このアプリケーションのすべてのイメージの取得に役立つ次の機能を見つけます。
// Get all the images needed for the app
Future<AppImages> getAppImages() async {
final Content content = Content();
final String homepageImage = appConfig['homePage'];
final String contactUsImage = appConfig['contactUs'];
final String logoImage = appConfig['logo'];
final String footerImage = appConfig['footerLogo'];
AppImages images;
try {
final dynamic data = await content.queryItems(<String, String>{
'q':
'(name eq "$homepageImage" OR name eq "$contactUsImage" OR name eq "$logoImage" OR name eq "$footerImage")',
'fields': 'all',
'expand': 'all',
});
final List<dynamic> items = data['items'] as List<dynamic>;
String homePageImageGUID,
contactUsImageGUID,
headerLogoGUID,
footerLogoGUID;
for (int i = 0; i < items.length; i++) {
final String name = items[i]['name'] as String;
final String id = items[i]['id'] as String;
if (name == homepageImage) {
homePageImageGUID = id;
} else if (name == contactUsImage) {
contactUsImageGUID = id;
} else if (name == logoImage) {
headerLogoGUID = id;
} else if (name == footerImage) {
footerLogoGUID = id;
}
}
//If any of the image ids are null, let the user know but continue loading the app
if (homePageImageGUID == null ||
contactUsImageGUID == null ||
headerLogoGUID == null ||
footerLogoGUID == null) {
print(kFileNameError);
}
images = AppImages(
headerLogoUrl: content.getRenditionURL(<String, String>{'id': headerLogoGUID}),
footerLogoUrl: content.getRenditionURL(<String, String>{'id': footerLogoGUID}),
contactUsImageUrl:
content.getMediumRenditionUrl(<String, String>{'id': contactUsImageGUID}),
homePageImageUrl: content.getMediumRenditionUrl(<String, String>{'id': homePageImageGUID}),
);
} catch (exception) {
rethrow;
}
return images;
}
;
これでデータ問合せができたので、Flutterコンポーネントでレスポンスをレンダリングできます。
フロッターコンポーネント
最小限のアプリケーションによって、各ページが複数の小さなコンポーネントに分割されます。
次のいくつかのセクションでは、各コンポーネントでFlutterがアプリケーションをどのようにレンダリングするかの概要を説明します。
LoadingScreenコンポーネント
LoadingScreenは、lib/screens/load_screen.dartにあるLoadingScreenコンポーネントによってレンダリングされるステートフル・ウィジェットです。
lib/screens/load_screen.dartファイルには、画面のデータを取得するためのすべてのコードが含まれており、service.dartに定義されている関数を呼び出します。
Future<void> getData() async {
final Services services = Services();
try {
final AppImages images = await services.getAppImages();
if (images != null) {
Navigator.push<dynamic>(context,
MaterialPageRoute<dynamic>(builder: (BuildContext context) {
return HomePage(appImages: images);
}));
}
} catch (exception) {
setState(() {
this.exception = exception.toString();
});
print(exception.toString());
}
}
コンポーネントは、getDataメソッドを使用して、service.dartファイルに定義されているメソッドを使用してデータを取得します。
HomePageコンポーネント
ホーム画面は、lib/screens/home_page.dartにあるHomePageコンポーネントによってレンダリングされます。
HomePageコンポーネントは、データを渡すLoadingScreenコンポーネントによって起動されます。サーバーから追加データは取得されません。
また、lib/components/screen_layout.dartファイルで定義された ScreenLayoutコンポーネント、およびlib/components/image_stack.dartファイルで定義された ImageStackコンポーネントも使用します。
ContactUsコンポーネント
「Contact Us」画面は、lib/screens/contact_us.dartにあるContactUsコンポーネントによってレンダリングされます。
ContactUsコンポーネントは、データを渡すlib/components/navdrawer.dartファイルで定義されているNavDrawerコンポーネントによって起動されます。サーバーから追加データは取得されません。また、lib/components/image_stack.dartファイルで定義されているImageStackコンポーネントも使用します。
タスク3:アプリケーションのデプロイメントの準備
Flutter最小限のサイトを構築したので、エミュレータまたはデバイスに展開し、問題をデバッグしてアプリケーションをプレビューしてから稼働する必要があります。
エディタのFlutter Webサイトの手順に従ってアプリケーションを実行します。
- エディタとしてAndroid Studioを使用している場合は、Android Studioのメイン・ツールバーを探します。
- ターゲット・セレクタで、アプリケーションを実行するAndroidデバイスを選択します。使用可能なものとしてリストされていない場合は、「ツール」→「Android」→「AVD Manager」を選択して作成します。詳細については、Managing AVDsを参照してください。
- ツールバーの「実行」アイコンをクリックするか、メニュー項目「実行」→「実行」を起動します。
まとめ
このチュートリアルでは、Flutterで最小限のサイトを作成し、GitHubで入手できます。このサイトでは、Oracle Content ManagementをヘッドレスCMSとして使用しています。最小限サイト・チュートリアル用に公開されたコンテンツのチャネルを使用してOracle Content Managementを設定および構成した後、Flutterサイトをインストールして実行し、必要なコンテンツをフェッチしてサイトを構築しました。
Flutterの詳細は、FlutterのWebサイトを参照してください。
Oracle Content Managementの重要な概念については、ドキュメンテーションを参照してください。
このようなサンプルは、Oracle Help CenterのOracle Content Managementサンプル・ページで確認できます。
ヘッドレスのOracle Content Managementを使用したFlutterで最小限のサイトを構築
F55477-01
2022年3月
Copyright © 2021, 2022, Oracle and/or its affiliates.
原本著者: Oracle Corporation