헤드리스 Oracle Content Management로 Flutter에서 최소 사이트 구축

소개

Flutter는 단일 코드베이스에서 아름답고 기본적으로 컴파일된 다중 플랫폼 애플리케이션을 구축하기 위한 Google의 오픈 소스 프레임워크입니다. Flutter 코드는 ARM 또는 Intel 시스템 코드와 JavaScript로 컴파일하여 모든 디바이스에서 빠른 성능을 제공합니다. Flutter는 Oracle Content Management에서 콘텐츠를 소비하는 애플리케이션을 구축하는 강력한 툴일 수 있습니다. 적합한 콘텐츠 모델로 무장하여 일반적인 블로그를 구성하는 Flutter UI를 빠르게 구축할 수 있습니다.

이 사용지침서에서는 Oracle Content Management를 헤드리스 CMS로 활용하여 Flutter에서 간단한 최소 사이트를 구축합니다. 이 Flutter 샘플은 GitHub에서 사용할 수 있습니다.

이 자습서는 세 개의 단계로 구성됩니다.

  1. Oracle Content Management 준비
  2. Flutter에서 최소 사이트 구축
  3. 배치용 응용 프로그램 준비

필요 조건

이 자습서를 진행하기 전에 먼저 다음 정보를 읽는 것이 좋습니다.

이 자습서를 따르려면 다음이 필요합니다.

구축 중인 제품

Flutter를 최소화하면 Oracle Content Management 저장소에서 이미지 및 기타 콘텐츠를 쉽게 검색할 수 있습니다.

현재 구축 중인 사항을 살펴보기 위해 자습서의 최종 상태인 Oracle Content Management의 콘텐츠를 소비하는 기본 Flutter 최소 사이트입니다.

다음은 이 자습서 끝부분에 나오는 홈 화면입니다.

이 이미지는 Flutter 최소 사이트에 대한 랜딩 페이지를 보여줍니다.

다음은 이 자습서 끝부분에 표시되는 연락처 화면입니다.

이 이미지는 Flutter 최소 사이트에 대한 연락처 페이지를 보여줍니다.

계속하려면 Oracle Content Management에 활성 가입하고 콘텐츠 관리자 롤로 로그인해야 합니다.

작업 1: Oracle Content Management 준비

Oracle Content Management 인스턴스가 아직 없는 경우 빠른 시작을 참조하여 Oracle Cloud에 등록하고, Oracle Content Management 인스턴스를 프로비전하고, Oracle Content Management를 헤드리스 CMS로 구성하는 방법을 알아보십시오.

이 자습서에서는 콘텐츠 모델을 생성해야 합니다. 빈 저장소를 콘텐츠 유형 및 연관된 콘텐츠로 채울 수 있는 다운로드 가능한 자산 팩이 있습니다.

Oracle Content Management를 준비하려면 다음을 수행합니다.

  1. 채널 및 자산 Repository 생성
  2. Oracle Content Management 샘플 자산 팩 임포트

채널 및 자산 저장소 생성

먼저 Oracle Content Management에서 채널 및 자산 저장소를 생성해야 콘텐츠를 게시할 수 있습니다.

Oracle Content Management에서 채널 및 자산 저장소를 생성하려면 다음을 수행하십시오.

  1. Oracle Content Management 웹 인터페이스에 관리자로 로그인합니다.

  2. 왼쪽 탐색 메뉴에서 콘텐츠를 선택한 다음 페이지 머리글의 선택 목록에서 채널 게시를 선택합니다.

    이 이미지는 [콘텐츠] 페이지 머리글의 드롭다운 메뉴에서 선택된 [게시 채널] 옵션을 보여줍니다.

  3. 오른쪽 맨 위에서 생성을 눌러 새 채널을 생성합니다. 이 자습서의 용도로 채널 이름을 'OCEMinimalChannel'로 지정하고 액세스를 공용으로 유지합니다. 저장을 눌러 채널을 생성합니다.

    이 이미지는 게시 채널 정의 패널을 보여줍니다. 채널 이름 필드에는 'OCEMinimalChannel'이 있습니다.

  4. 왼쪽 탐색 메뉴에서 콘텐츠를 선택한 다음 페이지 머리글의 선택 목록에서 저장소를 선택합니다.

    이 이미지는 [콘텐츠] 페이지 머리글의 드롭다운 메뉴에서 선택된 [저장소] 옵션을 보여줍니다.

  5. 오른쪽 맨 위에서 생성을 눌러 새 자산 저장소를 생성합니다. 이 자습서의 용도로 자산 저장소 이름을 'OCEMinimalRepository'로 지정합니다.

    이 이미지는 저장소 이름 필드에 'OCEMinimalRepository'가 있는 저장소 정의 패널을 보여줍니다.

  6. 게시 채널 필드에서 OCEMinimalChannel 채널을 선택하여 Oracle Content Management에 OCEMinimalRepository 저장소의 콘텐츠를 OCEMinimalChannel 채널에 게시할 수 있음을 나타냅니다. 완료되면 저장을 누릅니다.

    이 이미지는 [게시 채널] 필드에 'OCEMinimalChannel'가 있는 저장소 정의 패널을 보여줍니다.

Oracle Content Management 샘플 자산 팩 임포트

이 자습서에 필요한 모든 콘텐츠 유형 및 자산이 포함된 미리 구성된 Oracle Content Management 샘플 자산 팩을 다운로드할 수 있습니다.

Oracle Content Management 샘플 자산 팩에서 이 자습서에서 사용 중인 콘텐츠 사본을 업로드할 수 있습니다. 이렇게 하면 콘텐츠 유형을 테스트하고 콘텐츠를 수정할 수 있습니다. Oracle Content Management 샘플 자산 팩을 임포트하려면 자산 팩 아카이브 OCESamplesAssetPack.zip을 다운로드하여 선택한 디렉토리로 추출할 수 있습니다.

  1. Oracle Content Management 다운로드 페이지에서 Oracle Content Management 샘플 자산 팩(OCESamplesAssetPack.zip)을 다운로드합니다. 다운로드한 zip 파일을 컴퓨터의 위치로 추출합니다. 추출 후에 이 위치에는 OCEMinimal_data.zip이라는 파일이 포함됩니다.

  2. Oracle Content Management 웹 인터페이스에 관리자로 로그인합니다.

  3. 왼쪽 탐색 메뉴에서 콘텐츠를 선택한 다음 페이지 머리글의 선택 목록에서 저장소를 선택합니다. 이제 OCEMinimalRepository을 선택하고 상단 작업 표시줄에서 콘텐츠 임포트 단추를 누릅니다.

    이 이미지는 OCEMinimalRepository 항목이 선택된 [저장소] 페이지를 보여줍니다.

  4. 로컬 컴퓨터에서 OCEMinimal_data.zip을 Documents 폴더로 업로드합니다.

    이 이미지는 OCEMinimal_data.zip 파일의 업로드 확인 화면을 보여줍니다.

  5. 업로드되면 OCEMinimal_data.zip을 선택하고 확인을 눌러 자산 저장소로 콘텐츠를 임포트합니다.

    이 이미지는 [확인] 단추가 사용으로 설정된 선택된 OCEMinimal_data.zip 파일을 보여줍니다.

  6. 콘텐츠를 성공적으로 임포트한 후 자산 페이지로 이동하여 OCEMinimalRepository 저장소를 엽니다. 이제 모든 관련 이미지 및 콘텐츠 항목이 자산 저장소에 추가되었음을 알 수 있습니다.

    이 이미지는 OCEMinimalRepository 저장소를 보여주며 방금 임포트된 모든 자산을 보여줍니다.

  7. 왼쪽 상단에 있는 모두 선택을 누른 다음 게시를 눌러 이전에 생성한 게시 채널(OCEMinimalChannel)에 모든 임포트된 자산을 추가합니다.

    이 이미지는 모든 자산이 선택되고 작업 표시줄에 [게시] 옵션이 표시되는 OCEMinimalRepository 저장소를 보여줍니다.

  8. 게시하기 전에 모든 자산을 검증해야 합니다. 먼저 OCEMinimalChannel를 선택한 채널로 추가한 다음 검증 단추를 누릅니다.

    이 이미지는 [채널] 필드에 OCEMinimalChannel 채널이 추가된 [검증 결과] 페이지, 검증할 모든 자산 및 [검증] 단추가 사용으로 설정된 [검증 결과] 페이지를 보여줍니다.

  9. 자산이 검증되면 오른쪽 맨 위에 있는 게시 단추를 눌러 선택한 채널에 모든 자산을 게시할 수 있습니다.

    이 이미지는 [채널] 필드에 OCEMinimalChannel 채널이 추가되고, 검증된 모든 자산 및 [게시] 단추가 사용으로 설정된 [검증 결과] 페이지를 보여줍니다.

완료되면 자산 페이지에서 모든 자산이 게시되었음을 확인할 수 있습니다. (자산 이름 위의 아이콘으로 확인할 수 있습니다.)

이 이미지는 모든 자산이 게시된 [자산] 페이지를 보여줍니다.

작업 2: Flutter에서 최소 사이트 구축

Flutter 애플리케이션에서 Oracle Content Management 콘텐츠를 소비하기 위해 Flutter 최소 사이트 샘플을 사용할 수 있습니다. 이 샘플은 GitHub에서 오픈 소스 저장소로 제공됩니다.

주: Flutter 샘플 사용은 선택 사항이며 이 자습서에서 이 샘플을 사용하여 빠르게 시작할 수 있습니다. 또한 Flutter 애플리케이션을 직접 구축할 수도 있습니다.

Flutter에서 최소 사이트 구축은 다음 단계로 구성됩니다.

  1. Flutter 설치
  2. 샘플 저장소 복제 및 종속성 설치
  3. Flutter 애플리케이션 구성
  4. Oracle Content Management REST API를 사용하여 콘텐츠 인출

Flutter 설치

Flutter를 시작하기 위해 먼저 해야 할 일은 환경을 설정하는 것입니다. 플러터 웹사이트에서 설정하는 지침을 확인할 수 있습니다. 운영 체제에 해당하는 옵션을 사용합니다. 다음은 설치 단계에 대한 요약입니다.

  1. Flutter SDK를 다운로드합니다.
  2. 경로 환경 변수를 업데이트합니다.
  3. flutter doctor를 실행합니다.
  4. 플러터 웹 사이트에 설명된 단계에 따라 선택한 편집기를 설치합니다.
  5. Android Studio, IntelliJ, VS 코드 또는 Emacs용 편집기 플러그인을 추가합니다. 지침은 편집기에 Flutter 및 Dart 플러그인을 설치하는 방법을 지정합니다.
  6. 적절한 위치, 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의 게시된 자산에 대한 접근 권한을 제공합니다. 게시된 자산에는 콘텐츠 항목과 디지털 자산 및 해당 표현이 포함됩니다. 이제 최소 Flutter 애플리케이션으로 렌더링할 수 있도록 Oracle Content Management REST API를 활용하여 콘텐츠를 인출할 수 있습니다.

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/loading_screen.dart에 있는 LoadingScreen 구성요소에 의해 렌더링되는 Stateful 위젯입니다.

lib/screens/loading_screen.dart 파일에는 화면에 대한 데이터를 가져오는 모든 코드가 포함되며 services.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 메소드를 사용하여 services.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 최소 사이트를 구축했으므로 에뮬레이터 또는 장치에 배포해야 모든 문제를 디버그하고 응용 프로그램을 미리보기 할 수 있습니다.

편집기의 플러터 웹 사이트에 있는 지침에 따라 앱을 실행합니다.

  1. Android Studio를 편집기로 사용하는 경우 기본 Android Studio 도구 모음을 찾습니다.
  2. 대상 선택기에서 앱을 실행할 Android 장치를 선택합니다. 사용 가능한 것으로 나열된 항목이 없으면 도구 > Android > AVD Manager를 선택하고 여기에 만듭니다. 자세한 내용은 AVD 관리를 참조하십시오.
  3. 도구 모음에서 Run 아이콘을 누르거나 메뉴 항목 Run > Run을 호출합니다.

결론

이 자습서에서는 Flutter에서 GitHub에서 찾을 수 있는 최소 사이트를 생성했습니다. 이 사이트는 헤드리스 CMS로 Oracle Content Management를 사용합니다. 최소 사이트 자습서를 위해 게시된 콘텐츠 채널을 사용하여 Oracle Content Management를 설정하고 구성한 후 Flutter 사이트를 설치하고 실행하여 필요한 콘텐츠를 인출하고 사이트를 구축했습니다.

Flutter에 대한 자세한 내용은 Flutter 웹 사이트를 참조하십시오.

문서에서 중요한 Oracle Content Management 개념에 대해 알아봅니다.

Oracle Content Management 샘플 페이지의 Oracle Help Center에서 이와 같은 더 많은 샘플을 찾을 수 있습니다.