feat(cafe24): 상단 공통 홍보 숨기기 체크박스 (PC·모바일 동시)
요청은 스킨 detail.html 의 `const numbers = [...]` 를 고치는 것이었지만, 카페24
Admin API 로는 스킨 HTML 파일을 읽거나 쓸 수 없다. 확인 결과 테마는 조회만
가능하고(GET /admin/themes) 스킨 파일 엔드포인트가 없다. 쓸 수 있는 것은 테마
페이지와 스크립트 태그뿐이다.
그래서 같은 결과를 상품 상세설명 안의 CSS 로 낸다. 상세설명은 이미 우리가 쓸 수
있는 영역이고, 상품별로 켜고 끌 수 있으며, 상태가 그 상품 소스에 그대로 보인다.
새 권한이나 재인증도 필요하지 않다.
<style id="cf24-hide-common-promo">.edb-img-tag-w{display:none !important}</style>
id 로 우리 블록만 찾으므로 사람이 쓴 <style> 은 건드리지 않는다. 넣기/빼기는
멱등이고 소스 정리(format_html)를 거쳐도 상태가 유지된다.
PC·모바일 모두 반영한다. 미분리 상품은 같은 HTML 이 양쪽에 들어가고, 분리 상품은
모바일 본문을 건드리지 않되 이 블록만 모바일에도 맞춘다 — 양쪽에 걸지 않으면 한쪽에
홍보가 그대로 남는다. PC/모바일 상태가 다르면 화면에 불일치를 알린다.
"변경 없음" 판정에 모바일 변경도 포함시켰다. PC 는 그대로인데 모바일 숨김만
바뀌는 경우가 있어서, 예전 조건이면 아무 일도 하지 않고 끝났다.
스킨의 numbers 목록과는 독립이며 충돌하지 않는다(스킨은 요소 제거, 이쪽은 CSS 숨김).
이미 목록에 있는 상품은 그대로 두면 된다.
검증: 유닛테스트 49개 통과(신규 4개 — 추가/제거 왕복, 멱등, 포맷 통과 후 인식,
사람이 쓴 style 보존).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -368,6 +368,47 @@ def _collapse_short_blocks(lines: list[str]) -> list[str]:
|
||||
return out
|
||||
|
||||
|
||||
# ════════════════════════════════════════════════════════════
|
||||
# 상단 공통 홍보 숨기기
|
||||
#
|
||||
# 스킨(detail.html)에는 공통 홍보를 지울 상품번호 목록이 박혀 있다.
|
||||
# const numbers = [12,31,32, ...]; // .edb-img-tag-w 를 remove()
|
||||
# 그런데 카페24 Admin API 는 **스킨 파일을 읽거나 쓸 수 없다**(테마는 조회만).
|
||||
# 그래서 같은 결과를 상품 상세설명 안의 CSS 로 낸다 — 상세설명은 우리가 쓸 수 있고,
|
||||
# 상품별로 켜고 끌 수 있으며, 상태가 그 상품 소스에 그대로 보인다.
|
||||
#
|
||||
# id 를 붙여 우리가 넣은 블록임을 표시한다. 사람이 쓴 <style> 은 건드리지 않는다.
|
||||
# ════════════════════════════════════════════════════════════
|
||||
HIDE_PROMO_ID = "cf24-hide-common-promo"
|
||||
HIDE_PROMO_BLOCK = (
|
||||
f'<style id="{HIDE_PROMO_ID}">/* DBX ERP: 상단 공통 홍보 숨김 */\n'
|
||||
".edb-img-tag-w{display:none !important}\n"
|
||||
"</style>"
|
||||
)
|
||||
_HIDE_PROMO_RE = re.compile(
|
||||
r"[ \t]*<style[^>]*\bid\s*=\s*[\"']%s[\"'][^>]*>.*?</style>\s*" % re.escape(HIDE_PROMO_ID),
|
||||
re.IGNORECASE | re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def has_hidden_promo(html: str) -> bool:
|
||||
"""이 상품의 상세설명에 공통 홍보 숨김 블록이 들어 있는가."""
|
||||
return bool(_HIDE_PROMO_RE.search(html or ""))
|
||||
|
||||
|
||||
def set_promo_hidden(html: str, hidden: bool) -> str:
|
||||
"""숨김 블록을 넣거나 뺀다. 여러 번 호출해도 결과가 같다(멱등).
|
||||
|
||||
넣을 때는 맨 앞에 둔다 — 찾기 쉽고, 상세설명 어디에 있어도 CSS 효과는 같다.
|
||||
"""
|
||||
stripped = _HIDE_PROMO_RE.sub("", html or "")
|
||||
if not hidden:
|
||||
return stripped
|
||||
if not stripped.strip():
|
||||
return HIDE_PROMO_BLOCK
|
||||
return HIDE_PROMO_BLOCK + "\n" + stripped.lstrip("\n")
|
||||
|
||||
|
||||
def fingerprint(html: str) -> str:
|
||||
"""편집 시작 시점의 카페24 값 지문. 적용 직전 값과 비교해 충돌을 잡는다.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user