대표 이미지가 잘리는 이유, 템플릿 비율 3:2→16:9 차이

이미지가 잘리는 이유 — 템플릿마다 다른 화면비

작성자

카테고리:

이미지가 잘린다는 제보를 받았다. 대표 이미지에 넣은 ‘AgentLog’ 로고 텍스트가 앞글자 ‘A’만 잘려서 ‘gentLog’처럼 보인다는 캡처였다.

내 화면에서는 멀쩡했다. 데스크탑도, 모바일 에뮬레이션(브라우저에서 개발자 도구로 흉내 내는 모바일 화면)도 전부 정상이었다. 그래서 처음엔 캐시(cache, 웹사이트 속도를 높이려고 이전 화면을 임시 저장해두는 것) 문제라고 생각했다.

아니었다.

같은 이미지인데 왜 어디서는 잘릴까?

이미지 자체의 문제가 아니었다. 소스 이미지는 1200×675픽셀, 정확히 16:9 비율로 만들었다. 문제는 그 이미지를 감싸는 HTML 박스의 비율이 페이지마다 달랐다는 것이다.

블로그 홈 카드(목록 화면에서 글을 미리 보여주는 카드형 UI)에서는 이미지 박스가 16:9였다. 그런데 글 상세 페이지의 대표 이미지 블록(block, 워드프레스에서 콘텐츠를 구성하는 단위)은 3:2였다.

object-fit: cover는 이미지를 박스에 꽉 채우되, 비율이 안 맞으면 삐져나온 부분을 잘라낸다. 16:9 이미지를 3:2 박스에 넣으면 가로가 남는다. 남은 부분이 양옆에서 잘린다. 그래서 로고 텍스트의 왼쪽이 사라진 것이다.

CSS만 보고 “object-fit: cover면 다 똑같이 나오겠지” 하고 넘어갔으면 계속 몰랐을 문제다. 같은 이미지라도 어느 템플릿(template, 페이지 구조를 정해놓은 틀)에서 렌더링(rendering, 코드를 실제 화면으로 그려내는 것)되느냐에 따라 잘리는 방식이 완전히 달라진다.

curl로 실제 코드를 확인해보기, 원인은 HTML에 있었다

눈으로 확인이 안 되니까 curl(curl, 터미널에서 웹 주소로 요청을 보내 응답을 받아보는 도구)로 라이브 페이지의 실제 HTML을 직접 떠봤다.

홈 카드에서 뽑은 <img> 태그:

style="aspect-ratio:16/9"

글 상세 페이지에서 뽑은 <img> 태그:

style="aspect-ratio:3/2"

숫자가 달랐다. 홈 카드용 CSS는 직접 16:9로 맞춰놨는데, 글 상세 페이지는 워드프레스 테마 템플릿 자체의 대표 이미지 블록 설정이 3:2로 고정돼 있었다.

대표 이미지가 자꾸 잘려 보인 이유 — 템플릿마다 다른 비율(3:2 vs 16:9) 스크린샷 1

위 캡처가 그 차이를 그대로 보여준다. 같은 이미지, 다른 숫자 하나.

원인은 명확했다. 이제 고치면 됐다.

워드프레스 템플릿을 REST API로 수정하기

보통은 사이트 에디터(Site Editor, 워드프레스 관리자 화면에서 페이지 구조를 시각적으로 편집하는 도구) UI에 들어가서 블록을 클릭하고 비율 드롭다운을 바꾼다. 몇 번 클릭하면 끝나는 일이다.

그런데 워드프레스 최신 버전은 이 템플릿을 REST API(REST API, 웹에서 데이터를 주고받는 표준 방식. 주소에 요청을 보내면 결과가 돌아온다)로도 읽고 쓸 수 있다. 주소는 이렇다:

/wp-json/wp/v2/templates/{id}

이 엔드포인트의 정식 스펙은 워드프레스 공식 REST API Handbook에 나와 있다. GET 요청으로 템플릿 원본 콘텐츠를 읽어오면, 안에 이런 블록 설정이 문자열로 들어있다:

<!-- wp:post-featured-image {"aspectRatio":"3/2"} /-->

이 부분을 "aspectRatio":"16/9"로 바꾸고, POST 요청으로 다시 보내면 끝이다. UI를 열고 찾고 클릭하는 것보다 빠르다. 실수할 여지도 적다. 바꿀 문자열이 정확히 무엇인지 보이니까.

API 인증은 워드프레스 애플리케이션 비밀번호(Application Password, 관리자 화면 사용자 설정에서 발급하는 API 전용 비밀번호)를 쓰면 된다. curl에 -u 유저명:앱비밀번호를 붙이면 된다.

캐시가 삭제 안 될 때, save_post 훅으로 우회하기

템플릿은 고쳤다. 그런데 반영이 안 됐다.

이전에도 다뤘던 라이트스피드 캐시가 예전 3:2 버전 HTML을 계속 들고 있었다. 원래라면 관리자 화면 상단바의 ‘전체 캐시 삭제’ 버튼을 누르면 된다. 그런데 브라우저 자동화 도구가 그 시점에 완전히 죽어있었다. 관리자 화면 자체에 들어갈 수가 없었다. 몇 번을 재시도해도 ‘browser closed’ 에러만 떴다.

이건 좀 웃겼다. 템플릿은 API로 고쳐놨는데 캐시 하나 못 지워서 막힌 상황이었다.

라이트스피드 REST API에 캐시 퍼지 전용 엔드포인트가 있는지 먼저 찾아봤다. 없었다.

대신 워드프레스의 기본 동작을 이용했다. 글을 REST API로 다시 저장하면 , 실질적인 내용 변경 없이, status 값을 그대로 재전송해서 저장만 트리거하면 , 워드프레스의 save_post 훅이 실행된다. 라이트스피드는 이 훅에 연결돼 있어서, 훅이 실행되면 해당 글의 캐시를 자동으로 비운다.

발행된 글 8개, 예약된 글 6개. 총 14개를 이 방식으로 한 번씩 재저장시켰다.

캐시가 실제로 비워졌는지는 응답 헤더로 확인했다. curl에 -I 옵션을 붙이면 헤더만 볼 수 있다. x-litespeed-cache: miss가 뜨면 캐시 없이 원본 서버에서 응답이 온 것이다.

대표 이미지가 자꾸 잘려 보인 이유 ,  템플릿마다 다른 비율(3:2 vs 16:9) 스크린샷 2

miss가 확인된 다음에야 진짜 반영된 걸 믿었다.

초보자도 활용할 수 있는 API 우회법

UI가 막혔을 때 바로 포기하지 마라. 워드프레스는 REST API로 할 수 있는 일이 생각보다 많다.

  • 템플릿 읽기·쓰기: GET/POST /wp-json/wp/v2/templates/{id}
  • 글 저장 트리거: POST /wp-json/wp/v2/posts/{id} , 바디에 {"status":"publish"}만 넣어도 된다
  • 캐시 반영 확인: curl -I로 x-litespeed-cache 헤더 값을 본다

인증은 반드시 애플리케이션 비밀번호를 써야 한다. 관리자 계정 비밀번호를 API에 직접 쓰지 마라. 관리자 화면 → 사용자 → 프로필 → 애플리케이션 비밀번호 항목에서 발급하면 된다.

그리고 save_post 훅 방식은 캐시를 지우는 게 목적이지, 글 내용을 바꾸는 게 아니다. 실수로 status를 draft로 보내면 발행된 글이 비공개로 바뀐다. 요청 바디를 보내기 전에 현재 status 값을 GET으로 먼저 읽어야 한다. 당연한 말이지만 한 번은 짚고 넘어가야 한다.

예전에 홈페이지 메타 설명이 반영 안 됐던 문제도 비슷했다 , 설정 화면에 값이 있다고 실제로 쓰이는 건 아니었다.

이번 문제는 솔직히 이미지 생성 코드가 아니라 템플릿 설정을 끝까지 확인하지 않은 데서 생겼다. 홈 카드 CSS는 직접 썼으면서, 글 상세 페이지 템플릿 설정은 기본값을 그냥 믿었다.

다음에 이미지 비율을 다루는 기능을 만들면, 렌더링되는 페이지 전부의 템플릿 설정을 먼저 확인하고 시작할 것이다.

같은 워드프레스 주제로 이어서 읽으면 좋은 글: WPCode로 보안 헤더 추가하다 코드가 깨진 이유, 이미지가 삐져나가는 버그, 원인 찾고 자동화까지 한 후기, 워드프레스 SEO 플러그인 충돌 피하기 , 켜야 할 것, 꺼야 할 것.

JIN 아바타

작성자

소개 보기 →