본문으로 건너뛰기

Masonry Gallery(메이슨리 갤러리)

Masonry Gallery는 가로세로 비율이 서로 다른 이미지를 표시합니다. 각 이미지는 원래 비율을 유지한 채 가장 짧은 열에 배치되며, 사용자가 페이지를 아래로 스크롤하면 다음 데이터 페이지를 자동으로 추가합니다. 컨트롤 내부에 별도의 스크롤바를 만들지 않습니다.

포트폴리오, 사진, 아이디어 보드, 미디어 자산에 적합합니다. 업무 레코드의 상태, 메타데이터, 작업을 표시하는 CardSet과는 목적이 다릅니다.

컨트롤주요 목적데이터와 레이아웃
Masonry Gallery서로 다른 비율을 유지하는 이미지 중심 연속 탐색페이지 이미지 레코드 + 페이지 단위 무한 스크롤
CardSet상태, 메타데이터, 작업이 있는 업무 레코드 요약공통 카드 템플릿 + Pagination 또는 Load More
Grid페이지 영역과 컨트롤을 수동 배치고정 24열 레이아웃이며 레코드를 반복하지 않음

1. 컨트롤 추가​

  1. Page Designer에서 Containers를 엽니다.
  2. Masonry Gallery를 페이지로 끌어옵니다.
  3. Data Source를 먼저 구성한 후 필드를 매핑합니다.
  4. portfolioGallery 같은 안정적인 이름을 지정합니다.

디자인 캔버스에는 비율이 다른 예시 카드가 표시됩니다. Preview는 실제 데이터를 읽지만, 편집 중 계속 로딩되지 않도록 최대 두 페이지만 불러옵니다.

2. 데이터 소스​

Model Data Source, Custom API, Media Library, Object Storage를 지원합니다. Model과 Custom API는 업무 레코드를 반환하고, 마지막 두 유형은 서버 측 Media Connector를 사용합니다.

2.1 Custom API 샘플​

POST /spark/api/sample/masonry-gallery/images
속성값
URL/spark/api/sample/masonry-gallery/images
Request MethodPOST
Rows Pathdata.records
Total Pathdata.total
Current Page Pathdata.current
Page Size Pathdata.pageSize

Test & Import로 한 페이지를 요청하고 다음 Response Fields를 가져옵니다.

Field PathData Type용도
idTEXT고유 키
imageUrlURL이미지 주소
titleTEXT이미지 제목
captionTEXT보충 설명
badgeTEXT분류 배지
altTEXT대체 텍스트
widthNUMBER원본 너비
heightNUMBER원본 높이

요청 본문에는 페이지 정보가 포함됩니다.

{"current": 1, "pageSize": 6}
{
"success": true,
"data": {
"current": 1,
"pageSize": 6,
"total": 24,
"records": [{
"id": "gallery-1",
"imageUrl": "/spark/api/sample/masonry-gallery/assets/coastal-architecture.jpg",
"title": "Coastal Geometry",
"caption": "Sunlit concrete forms above a quiet blue sea.",
"badge": "Architecture",
"alt": "White coastal architecture above the sea",
"width": 1200,
"height": 1200
}]
}
}

total이 가장 확실한 종료 조건입니다. 없으면 한 페이지의 레코드 수가 Items Per Request보다 적을 때 종료합니다. Row Unique Key는 모든 페이지에서 고유해야 하며 중복 키는 제거됩니다.

2.1 Media Library와 Object Storage​

먼저 App Settings → Integrations → Media Connections에서 재사용 가능한 연결을 만듭니다.

  1. Console Secret Management에서 자격 증명을 만듭니다. OSS/S3/MinIO는 OBJECT_STORAGE, 미디어 플랫폼은 MEDIA_PROVIDER를 사용합니다.
  2. Media Connections에서 Provider와 기존 Secret을 선택합니다. 폼에는 해당 Provider에 필요한 설정만 표시되며 자동으로 사용하는 공식 API Endpoint는 표시하지 않습니다.
  3. Masonry Gallery Data Source에서 Media Library 또는 Object Storage를 선택하고 Connection만 참조합니다. 이후 Collection/Container, Path, 필터, Page Size를 설정합니다.
  4. Test를 실행합니다. Test, 디자인 미리보기, 런타임은 같은 Media Gateway와 응답 파서를 사용합니다.

현재 사용 가능한 운영 Provider:

ProviderSecret ManagementMedia Connection 설정
CloudinaryMEDIA_PROVIDER; API Key에는 API Key, API Secret에는 API Secret 입력Cloud Name 필수, Root Folder 선택
ImageKitMEDIA_PROVIDER; API Key에는 Public API Key, API Secret에는 Private API Key 입력Root Folder 선택, 공식 API Endpoint 자동 사용
Aliyun OSS / AWS S3 / MinIOOBJECT_STORAGE; Access Key와 Access Secret 입력스토리지에 맞게 Endpoint, 기본 Bucket, Root Prefix 설정

Spark Sample Media Library는 외부 계정이 필요 없는 개발용 샘플입니다. Cloudinary와 ImageKit은 운영 Media Library Connector이며 Bynder, AEM Assets, 완전한 Spark Media Library는 아직 제공되지 않습니다.

페이지 JSON에는 secretId, 액세스 키, 임시 서명 URL이 저장되지 않습니다. 백엔드는 응답을 records, nextCursor, hasMore, 선택적 total 형식으로 정규화합니다. 카드는 thumbnailUrl, 전체 화면 보기는 imageUrl을 사용합니다.

{
"records": [{
"id": "asset-001",
"imageUrl": "https://cdn.example/full.webp",
"thumbnailUrl": "https://cdn.example/card.webp",
"title": "Summer campaign",
"alt": "Summer campaign launch",
"width": 1600,
"height": 1067
}],
"nextCursor": "opaque-next-cursor",
"hasMore": true,
"total": null
}

실행 가능한 예제는 spark-sample의 SampleMasonryMediaConnector.java, masonry-gallery-media-connection.json, masonry-gallery-media-page.json에 있습니다.

3. 필드 매핑​

속성권장 매핑필수 여부
Row Unique Keyid필수
Image URL FieldimageUrl필수
Title Fieldtitle선택
Caption Fieldcaption선택
Badge Fieldbadge선택
Alternative Text Fieldalt권장
Image Width Fieldwidth권장
Image Height Fieldheight권장

Advanced의 Width와 Height를 함께 설정하면 이미지 다운로드 전에 올바른 비율의 공간을 확보하여 레이아웃 이동을 줄입니다. Alternative Text는 파일명이 아니라 이미지 내용을 설명해야 하며, 누락되면 Title을 사용합니다.

4. 반응형 레이아웃​

속성권장값설명
Desktop Columns4넓은 화면의 열 수
Tablet Columns3중간 화면의 열 수
Mobile Columns2, 텍스트가 많으면 1모바일 열 수
SpacingDEFAULTCOMPACT, DEFAULT, RELAXED
Items Per Request6 또는 12요청당 로드 수

열 수는 페이지 너비에 따라 바뀌며 이미지를 동일한 높이로 자르지 않습니다.

5. 스크롤 로딩​

현재 끝에서 약 1.5 화면 거리에 도달하면 다음 페이지를 불러옵니다. 동시에 하나의 요청만 실행합니다. 로딩, Retry 가능한 오류, 완료 상태가 표시됩니다. 잠시 후 페이지로 돌아오면 이미 불러온 레코드와 스크롤 위치를 복원합니다.

자체 스크롤바가 있는 좁고 고정 높이인 컨테이너 안에는 배치하지 마십시오.

6. 전체 화면 미리보기와 상호작용​

Enable Fullscreen Preview를 켜면 클릭으로 뷰어를 엽니다. 좌우 버튼과 방향키, Escape, Tab, Enter, Space를 지원합니다.

onClick 전에 선택된 레코드를 Current Record에 기록합니다.

record.id
record.imageUrl
record.title
record.badge

한 번의 클릭으로 미리보기와 onClick을 모두 실행할 수 있습니다. 상호작용이 즉시 다른 페이지로 이동한다면 Fullscreen Preview를 끄십시오.

함수동작
reloadGallery상태를 비우고 첫 페이지부터 다시 로드
setGalleryData레코드를 직접 교체하고 자동 페이지 로딩 종료

7. 요청 컨텍스트와 백엔드​

Data Source 테스트, 디자인 미리보기, 실행 화면은 같은 요청 로직을 사용하며 Spark가 다음 Header를 자동으로 보냅니다.

Header값
X-Spark-Page-EnvironmentDEV, TEST, PROD
X-Spark-Page-Render-ModeDESIGN_PREVIEW, RUNTIME

Data Source에 직접 추가하지 마십시오. 백엔드는 SparkPageRequestHeaders.resolve로 해석하고 디자인 미리보기에서 더 짧은 데이터 집합을 반환할 수 있습니다.

@PostMapping
public ApiResult<ProTablePageResult<MasonryGalleryImageDTO>> queryByPost(
@RequestBody(required = false) MasonryGalleryQueryRequest request,
@RequestHeader(value = SparkPageRequestHeaders.ENVIRONMENT, required = false) String environment,
@RequestHeader(value = SparkPageRequestHeaders.RENDER_MODE, required = false) String renderMode) {
return SparkApiResultHelper.success(
Locale.ENGLISH,
galleryService.query(request,
SparkPageRequestHeaders.resolve(environment, renderMode)),
"SPARK-SAMPLE-MASONRY-GALLERY-0001");
}

Service는 렌더링 모드에 따라 데이터 크기를 선택합니다.

int total = requestContext != null
&& requestContext.getRenderMode() == SparkPageRenderMode.DESIGN_PREVIEW
? 12
: 24;

Java 코드, 페이지 JSON, 이미지는 spark-sample에 있습니다. 전체 규약은 페이지 요청 컨텍스트를 참조하십시오.

8. 성능 및 데이터 권장 사항​

  • 표시 크기에 맞는 압축 이미지를 캐시하여 제공합니다.
  • 안정적인 id, width, height, 의미 있는 alt를 반환합니다.
  • 요청당 6~20개를 사용하고 백엔드 정렬을 안정적으로 유지합니다.
  • 이미지 요청 실패와 데이터 API 실패는 별도로 확인합니다. 이미지 하나가 실패해도 다음 페이지 로드는 중단되지 않습니다.

9. 자주 발생하는 문제​

  • 같은 이미지가 반복됨: 백엔드가 current와 pageSize를 실제 페이징에 사용하는지, 응답 경로가 올바른지 확인합니다.
  • 스크롤해도 더 이상 요청하지 않음: total, 짧은 페이지, Retry 대기 중인 실패 요청을 확인합니다.
  • 레이아웃이 크게 이동함: width와 height를 반환하고 매핑합니다.
  • 이미지가 자리 표시자로 보임: Image URL Field, 인증, CORS를 확인합니다.
  • 업무 작업과 풍부한 메타데이터가 필요함: CardSet을 사용합니다. Masonry Gallery는 Card Actions를 제공하지 않습니다.