WordPress 20초 핵심 요약 중복 삽입 버그 제목 정규식 수정 작업 기록
2026년 8월 6일 공개 글을 다시 확인하다가 WordPress 20초 핵심 요약 중복 삽입 버그를 발견했다. 작성된 제목은 하나여야 했지만 공개 HTML에는 같은 H2가 2개였고, 플러그인이 만든 자동 요약 상자도 1개 남아 있었다.
이번 기록은 huntlab-article-toc v1.1.6과 커밋 ffd304f를 기준으로 증상을 센 방법, 제목 정규식 두 곳을 고친 이유, 배포 중 막힌 지점과 공개 DOM 채택 기준을 다룬다. Linux Cron 컨테이너에서 저장소의 Python 테스트는 다시 실행했지만 PHP CLI가 없어 PHP 런타임 재현은 하지 못했다.
20초 핵심 요약
- 무엇: 작성 요약과 WordPress 플러그인 자동 요약이 중복되는 공개 렌더링 경로를 정규식 수정으로 보정한다.
- 왜: 20초 접두어를 감지하지 못하면 자동 상자와 H2가 함께 남아 독자에게 빈 요약 또는 중복 요약이 보일 수 있기 때문이다.
- 어떻게: 정규식 diff, 97개 테스트, 공개 DOM의 H2·요약 상자 개수를 순서대로 대조해 수정 결과를 확인한다.
한눈에 보기
- 무엇: 작성한 요약과 플러그인 자동 요약이 함께 표시된 WordPress 렌더링 버그 수정 기록이다.
- 왜: 기존 정규식이 제목의
20초접두어를 놓쳐 자동 상자와 같은 H2, fallback 문구가 공개 글에 남았다. - 어떻게: 공개 DOM 개수, 커밋 diff, 97개 Python 테스트, 배포 실패와 캐시 우회 재검사를 차례로 확인한다.
작업 기록: H2 두 개에서 공개 DOM 1개까지
자동 상자와 제목을 따로 셌다
처음 확인한 공개 HTML에는 .huntlab-article-quick-summary가 1개, 같은 제목의 <h2>가 2개 있었다. 무엇 값은 비어 있었고 자동 생성용 fallback 문구 두 개도 남아 있었다. H2 개수만 보면 원문이 중복 저장됐는지 렌더링 단계에서 추가됐는지 구분할 수 없어 자동 요약 클래스, 제목, fallback 문구를 따로 셌다.
이 조합은 작성 요약이 이미 있는데도 자동 생성 차단이 작동하지 않은 경로를 가리켰다. 처음에는 복잡한 필터 순서를 의심할 여지가 있었지만, 소스와 테스트를 따라가자 기존 감지 규칙이 핵심 요약만 찾고 제목 앞의 20초는 허용하지 않는다는 차이가 드러났다.
생성 차단과 후보 제외 규칙을 함께 바꿨다
커밋 ffd304f에서 플러그인 버전을 1.1.5에서 1.1.6으로 올리고 두 정규식에 같은 선택적 접두어를 반영했다.
- 핵심 요약
+ (?:20초\s*)?핵심 요약
첫 번째 수정 지점은 huntlab_article_quick_summary()의 조기 반환 조건이다. 이미 작성된 요약 제목을 찾으면 플러그인이 자동 상자를 만들지 않게 한다. 두 번째는 $sections를 순회하며 요약 제목을 자동 요약의 단계 후보에서 제외하는 조건이다. 한쪽만 고치면 자동 상자를 막더라도 요약 제목을 생성 재료로 취급하는 불일치가 남을 수 있어 두 규칙의 제목 문법을 함께 맞췄다.
(?:20초\s*)?의 마지막 ?는 접두어 그룹을 선택 사항으로 만든다. 따라서 기존 핵심 요약과 새 표준 제목을 모두 감지한다. PHP 공식 문서에서 preg_match()는 일치 시 1, 불일치 시 0, 실패 시 false를 반환한다.
Publisher 쪽에도 해당 Markdown H2가 정확히 하나인지 검사하고 fallback 문구를 거절하는 규칙을 추가했다. 작성 규칙과 렌더링 규칙이 다시 갈라지지 않도록 저장소 양쪽에 방어선을 둔 셈이다.
97개 테스트 통과가 배포 완료를 뜻하지는 않았다
2026년 8월 6일 Linux Cron 컨테이너에서 저장소 전체 Python 테스트를 다시 실행했다. 출력은 다음과 같다.
$ python -m unittest discover -s tests -p 'test_*.py'
.................................................................................................
----------------------------------------------------------------------
Ran 97 tests in 0.279s
OK
exit status: 0

97개가 모두 통과했지만 이를 PHP 함수 단위 테스트라고 부를 수는 없다. 플러그인 관련 검사는 주로 소스에 수정 패턴이 있는지 확인하는 구조 테스트다. 같은 <h2>20초 핵심 요약</h2> 입력을 사용한 Python 통제 비교에서는 기존 패턴이 old_match=0, 수정 패턴이 new_match=1이었다. 이 결과는 패턴 의도의 차이를 보여주지만 PHP PCRE와 WordPress 통합 실행을 대신하지 않는다.
PHP 런타임 확인은 환경에서 바로 막혔다.
$ php -v
/bin/bash: line 2: php: command not found
exit_status=127
실패 원인은 수정 코드가 아니라 조사 컨테이너에 PHP CLI가 없었던 것이다. 따라서 이번 재확인에서는 huntlab_article_quick_summary()를 PHP로 직접 실행하지 못했다.
ZIP과 nonce 실패 뒤 변경 파일만 적용했다
테스트 다음 단계도 매끄럽지 않았다. 플러그인 ZIP 전체 교체는 권한이 다른 .bak 파일 때문에 부분 실패했다. 권한을 강제로 바꾸거나 해당 파일을 삭제하지 않고 WordPress 플러그인 편집 경로로 변경된 PHP 파일 하나만 갱신하기로 했다.
첫 편집 시도에서는 페이지에 있는 여러 nonce 가운데 다른 값을 골라 실패했다. 도구가 편집 전용 nonce를 선택하도록 수정한 뒤 파일 적용에 성공했다. 관리자 화면의 성공 메시지만으로 작업을 끝내지 않고 캐시를 우회한 공개 URL에서 처음과 같은 세 항목을 다시 셌다.
| 공개 HTML 항목 | 수정 전 | 수정 후 |
|---|---|---|
| 자동 요약 클래스 | 1 | 0 |
| 작성한 제목 H2 | 2 | 1 |
| fallback 문구 두 종류 | 남아 있음 | 각각 0 |
작성한 H2 1개가 남고 자동 상자와 fallback이 모두 사라져야 수정 완료로 채택했다. 이 기준을 만족하지 않았다면 테스트가 통과했더라도 캐시, 배포 파일, 활성 플러그인 버전을 다시 확인할 계획이었다.
the_content 훅은 수정 위치이지 직접 원인은 아니었다
WordPress 공식 문서에서 the_content 훅은 콘텐츠를 화면에 표시하기 전에 필터링하는 지점이며, 콜백은 수정한 $content를 반환한다. 현행 플러그인은 add_filter( 'the_content', 'huntlab_article_toc_content', 20 )으로 콜백을 등록하고 관리자 화면, 단일 글, 루프, 메인 쿼리 조건을 확인한다. is_main_query()와 in_the_loop()는 보조 쿼리나 루프 밖 콘텐츠에 적용되는 범위를 줄이는 데 관련된다.
priority 20은 실행 순서를 설명할 뿐 이번 중복의 직접 원인은 아니었다. 정상 단일 글 경로에서도 조기 반환 정규식이 작성된 제목을 놓치면 자동 상자를 추가할 수 있다. 이번 전후 관측이 입증한 것은 해당 제목을 감지해 자동 요약을 만들지 않는 경로이며, 훅이 두 번 호출됐거나 재귀가 발생했다고 단정할 근거는 없다.
운영 결정과 아직 남은 문제
이번 작업에서 재사용할 판단은 제목 문법을 소비하는 규칙을 한꺼번에 찾는 것이다. 자동 생성 여부를 결정하는 정규식과 생성 후보에서 제외하는 정규식이 같은 변형을 받아들여야 하며, 저장소 테스트와 공개 렌더 결과도 별도로 확인해야 한다.
권한이 다른 기존 .bak 파일은 그대로 남아 있다. 동일한 필터 결과에 the_content가 다시 적용될 때 목차 HTML 전체가 완전히 같게 유지되는지도 아직 확인하지 못했다. 이 부분은 PHP 런타임 회귀 테스트가 마련되기 전까지 보류하며, 검색엔진 캐시와 기존 검색결과 스니펫의 반영 시점도 이번 결과로 보장하지 않는다.
자동 삽입 플러그인을 수정한다면 로컬 테스트 통과 기록과 함께 캐시를 우회한 공개 DOM의 작성 요소·자동 요소·fallback 개수를 남겨야 한다. 테스트 성공과 운영 반영 성공을 같은 결과로 취급하지 않는 가장 짧은 방법이다.
같은 운영 안전성 맥락의 변경 전 확인 절차는 WordPress 변경 전 백업·검증 기록에서 이어서 볼 수 있다.