워드프레스 사이트 내에 정의된 택소노미 텀들을 정리하는 두구입니다. 블로그를 오래 운영하면서 그래도 자잘한 글들을 쓰다 보니 태그가 많이 쌓입니다.
그런데 태그를 기분대로 만들다 보니, 태그 분류의 응집력이 너무 떨어집니다. 태그가 글들을 상세하게 분류하는 것도 나름 중요하지만, 불필요하게 태그가 중복되기도 하고, 태그 하나에 포스트가 겨우 하나씩만 대응되기도 합니다. 그런 것들은 재고의 여지가 있습니다.
파편화된 태그를 모아 좀 더 응집력 있는 태그로 만든다… 컨셉은 좋습니다. 의외로 WordPress.org 에 올라온 플러그인도 많지 않습니다. 이게 해 보면 단순한 작업일 것 같지만 파편화된 텀을 일관성있게 묶게 시각화하는 UI 작업이 간단하지가 않은 것 같습니다.
그래도 일단 초기의 컨셉을 다듬고 수정한 1.0.0 버전을 만들었습니다. 실제 텀들을 삭제하는 작업을 포함하므로 아직은 좀 더 테스트가 필요하겠습니다. 실제로 운영된 블로그에 설치해서 내부 테스트를 하니, 아직은 좀 더 필요한 부분들이 많은 것 같습니다.
병합 방법
관리자 > 도구 > Terms Merger 에서 찾을 수 있습니다. 텀을 헤집는 녀석이라 관리자 권한이어야만 접근이 가능하도록 설정햇습니다.
화면에 두 개의 탭이 나옵니다. 하나는 Terms, 하나는 Slots 입니다.
Terms 에서는 택소노미별 텀을 늘어놓습니다. Slots 에서는 병합할 텀들을 모으고 점검합니다.
Terms 에서 아래 그림처럼 텀을 선택하고 슬롯을 지정합니다. 그러면 해당 텀은 그 슬롯에 배당됩니다.
텀들을 슬롯에 모으면, Slots 탭으로 이동하여 슬롯에 담긴 텀을 확인해 볼 수 있습니다.
1 Add new slot 버튼을 누르면 슬롯을 더 만들 수 있습니다. 최대 10개까지 생성이 가능합니다. 즉, 텀을 1번부터 10번 슬롯 중 하나에 담아서 분류를 할 수 있게 되는 것입니다.
이 때 Assigned term(s) 에 내가 쌓아둔 텀들의 목록이 나타납니다. x를 누르면 슬롯에서 삭제할 수 있습니다.
2 Header term 은 실제 병합을 할 때 어떤 텀을 대상으로 병합할지 기준을 정하는 것입니다. 파란색으로 하이라이트된 텀이 헤더 텀입니다. 위 그림에서는 ‘admin-ajax.php’라는 텀을 기준으로 나머지 텀들이 병합됩니다.
3 Merge Terms 를 누르면 병합이 진행됩니다. 진행하기 전 경고창이 떠서 재차 확인을 요구합니다.
4 Remove this slot 은 슬롯을 지우는 명령입니다. 슬롯만 삭제되고 텀에는 아무런 영향이 없습니다.
많은 개선점이 …
UI가 그다지 간단하지는 않았습니다. 많은 디테일한 점이 필요한 것으로 보입니다. 개발된 플러그인을 제 블로그에 설치하여, 나름 실사 블로그 사이트에 쌓인 태그 데이터를 대상으로 테스트해 보았습니다. 그래 보니 실제 사용에 있어 사용자가 정말 편리하게 텀을 분석하고 관리하려면 아직 부족한 점이 많다는 것을 느낍니다. 그래도 이 정도 개발을 진행한 것에 보람을 느끼며 포스팅을 올립니다.
좀 더 완성도를 올리면 wordpress.org 에 올려 볼까 고민하고 있습니다. 혹시 원하는 분이 계시다면 github repository에서 다운로드 받아 테스트해 보세요.
워드프레스에서 일반적인 포스트는 관리자 > 설정 > 고유주소에서 적절히 주소 체계를 수정할 수 있지만, 커스텀 포스트의 주소 체계는 딱 고정되어 있다. 보통 <커스텀 포스트 타입 이름>/<포스트 이름(postname, 또는 slug)> 으로 되어 있으며, <커스텀 포스 타입 이름> , 즉 “앞부분” 정도만 register_post_type() 함수의 파라미터 조정을 통해 변경할 수 있다.
우선 앞부분을 변경하는 방법부터 설명한다. ‘my-cpt’란 포스트 타입을 위 예제처럼 입력했을 때, ‘rewrite’ 파라미터 ‘slug’ 항목을 ‘cpt’로 변경하였다. 그러므로 이 타입 포스트들의 URL은 이제 /cpt/<포스트 이름> 체계를 따르게 된다. 임의로 cpt라는 문자열을 주었고 이 문자열은 슬래시도 허용한다. 그러므로 ‘my/cpt’ 같이 줘도 문제 없다.
“뒷부분” 변경하기
앞부분은 아주 쉽게 변경 가능하다. 문제는 뒷부분이다. 커스텀 포스트는 자유롭게 이 뒷부분을 변경할 수 없으며, 포스트 이름으로 고정되어 있다. 가령 이 부분을 포스트의 ID로 변경하려고 한다. 하지만 프론트엔드에서 만날 수 있는 설정으로는 이것이 불가능하다.
그럼 별도의 액션/필터를 활용하여 이 부분을 수정해 보자. 우선 목표부터 좀 설명하기 쉽게 정리하자.
목표: My CPT 타입의 포스트 ID 2476의 포스트 이름은 'aaaa'다.
현재 주소는 /cpt/aaaa/ 이다. 이것을 /cpt/2476/ 으로 변경한다.
워드프레스의 URL 매칭과 메인 쿼리 방식을 생각했을 때, 위 목표를 가능하게 하려면 다음과 같은 3가지를 작업해야 한다.
워드프레스가 커스텀 포스트를 등록할 때, 하드코딩된 permastruct(고유주소 구조)를 포스트 이름 기반에서 포스트 아이디 기반으로 수정할 것.
커스텀 포스트의 퍼마링크를 가져올 때, 정확한 주소가 나오는지 확인하고 수정할 것.
rewrite_rule 을 생성할 때 포스트 아이디 기반 다시 쓰기가 메인 쿼리에서 정확히 쿼리될 수 있는지 파라미터를 확인하고 수정할 것.
변경 #1: permastruct 수정
커스텀 포스트의 permastruct (고유주소 구조)는 커스텀 포스트 등록시, 포스트의 이름으로 고정되어 있다. 구현부는 WP_Post_Type::add_permastruct() 메소드를 참고한다.
이것을 수정하려면 ‘registered_post_type’ 액션을 사용하여 글로벌 변수 $wp_rewrite에 접근한다. 그리고 여기서 등록된 내역을 수정한다.
‘%post_id%’를 넣어준 덕분에 ‘슬래시가 아닌 아무 문자열’ 정규식 부분이 ‘연속된 숫자’로 변경된 것을 볼 수 있다.
변경 #2: permalink 수정
다시 쓰기 규칙이 변경되었으니, 이제 “/cpt/2476/”으로 주소가 변경되었을 것 같지만, 아직은 부족하다. 포스트 편집기에서 보면 퍼마링크가 생뚱맞게 “/cpt/%post_id%/”로 나올 것이다. 이것은 get_permalink() 함수가 커스텀 포스트에 대해서는 %post_id%라는 치환 문자열을 고려하지 않기 때문이다.
생뚱맞은 %post_id% 가 URL 주소로.
이 문제는 ‘post_type_link’ 필터를 통해 해결이 가능하다. 아래 코드까지 붙여 넣는다.
이제 URL 주소가 그럴듯하게 나온다! 코드를 수정한 후 반드시 관리자 > 설정 > 고유주소를 재방문하여 rewrite_rule을 다시 생성해야 하는 것을 잊지 말자.
URL이 수정되었다.
변경 #3: rewrite_rule 수정
주소는 올바르게 찍히지만, 해당 주소로 들어갔을 때 404 NOT FOUND 페이지가 나온다. 아직 한 가지가 부족하다. 아까 다시 쓰기를 했을 때 규칙을 보자.
정규 표현식: cpt/([0-9]+)(?:/([0-9]+))?/?$
다시 쓰기: index.php?p=$matches[1]&page=$matches[2]
다시 쓰기에서 p=$matches[1] 부분이 중요하다. 우리가 ‘/cpt/2476/’ 경로로 들어왔을 때, 이것은 ‘index.php?p=2476&page=’로 치환된다. 여기서 포스트 ID 2476번을 쿼리하라는 명령은 올바르게 전달되지만, 포스트 타입 파라미터가 생략되어 있다. 포스트 타입 파라미터가 생략되면 기본값인 ‘post’가 사용된다. 그러므로 실제로 SQL 쿼리문은 다음처럼 입력되어버린다.