대부분의 WordPress 플러그인 개발은 같은 곡선을 그립니다. 누군가에게 예약 양식이나 피드 수집기, 결제 화면의 추가 입력란이 필요해지고, 개발자가 그것을 작성하고, 잘 동작하고, 모두가 다음 일로 넘어갑니다. 2년 뒤 그 사이트는 오래된 버전의 WordPress에 묶여 있습니다. 업데이트를 해도 그 플러그인이 무사할지 아무도 확신하지 못하고, 그것을 작성한 사람은 이미 떠났기 때문입니다.

원인이 코어가 너무 빨리 움직이는 데 있는 경우는 드뭅니다. WordPress는 호환성을 깨뜨리는 일에 보수적이고, 5년 전에 잘 작성된 플러그인 상당수는 지금도 WordPress 7.1에서 손대지 않은 채 돌아갑니다. 플러그인이 깨지는 이유는 첫 주에 내린 결정들입니다. 기능을 테마에 넣은 것, 훅을 쓰는 대신 코어 파일을 고친 것, 데이터를 가장 손쉬운 구조에 담아 둔 것, 그리고 누구도 릴리스 후보에서 시험해 보지 않은 것입니다.

맞춤형 WordPress 플러그인이 코어 업데이트를 견디게 하는 것은 무엇일까요. 네 가지입니다. 코드가 테마가 아니라 플러그인 안에 있을 것. 코어 파일을 고치는 대신 액션과 필터로 WordPress를 확장할 것. 데이터마다 그 형태에 맞는 구조에 저장할 것. 그리고 릴리스가 배포되기 전에 누군가가 모든 릴리스 후보를 상대로 시험해 볼 것.


WordPress 플러그인 개발이 테마가 아니라 플러그인에 속하는 이유

맞춤 코드의 기본 거처는 테마의 functions.php입니다. 이미 거기에 있고 이미 실행되기 때문입니다. 그리고 그것은 다음 리뉴얼에서 사라지는 파일이기도 합니다.

테마는 표현입니다. 테마를 바꾸면 예전 테마가 하던 일은 전부 멈춥니다. 커스텀 게시물 타입은 더 이상 등록되지 않아 콘텐츠가 관리 화면도 고유주소도 없이 데이터베이스에 남습니다. 숏코드는 페이지 한가운데에 날것의 문자열로 나타납니다. 분석 스니펫과 스키마 마크업, CRM으로 보내던 야간 호출도 함께 사라지는데 오류는 하나도 나지 않습니다.

규칙은 발주서에 적을 수 있을 만큼 단순합니다. 리뉴얼 이후에도 여전히 참이어야 하는 것은 모두 플러그인에 들어갑니다. 커스텀 게시물 타입과 분류, 외부 시스템과의 연동, 숏코드와 블록, 업무 규칙, 예약 작업, 그리고 데이터베이스에 쓰는 모든 것입니다. 테마에는 템플릿과 스타일과 템플릿 파트가 남습니다.

청구서는 뒤늦게 도착합니다. 다음 리뉴얼 때 이미 존재하던 것을 다시 만드는 값을 또 치르거나, 예전 functions.php를 그대로 들고 가야 합니다. 몇 년치 스니펫이 쌓인 사이트라면 이것은 피할 수 있었던 수천 파운드의 작업이고, 리뉴얼 견적이 고객이 예상한 금액의 두 배로 돌아오는 이유이기도 합니다. 자식 테마도 여전히 테마입니다.

확장 모델, 그리고 정말 중요한 단 하나의 규칙

WordPress는 바깥에서 바꾸도록 만들어졌습니다. 그 장치가 훅이고, 훅 문서는 훅을 한 코드가 다른 코드에 개입하거나 그것을 수정할 수 있는 미리 정해진 지점이라고 설명합니다. 액션은 정해진 순간에 발생해 무언가를 하게 해 줍니다. 글이 발행된 뒤 알림을 보내거나 게시물 타입을 등록하는 식입니다. 필터는 값을 건네주며 그것을 바꾸거나 그대로 두기를 기대하고, 다시 돌려주기를 기대합니다.

여기서 따라 나오는 규칙은 절대적입니다. wp-admin이나 wp-includes, 또는 다른 플러그인의 디렉터리 안에 있는 파일을 고치고 있다면 이미 진 것입니다. 그 수정은 다음 업데이트에서 지워집니다. 경고도 오류도 없고, 대개는 무언가가 동작을 멈췄다고 고객이 알려 줄 때까지 아무도 알아채지 못합니다. 개발자를 뽑기 전에 이것을 직접 물어보십시오.

필요한 훅이 없을 때는 동작을 대체하는 대신 감싸거나, 더 넓은 훅으로 올라가거나, 서드파티 플러그인을 버전 관리 아래에서 포크하고 차이를 문서로 남기거나, 상류에 훅을 추가해 달라고 요청하십시오. 지금 있는 훅 대부분이 그렇게 추가되었습니다.

이름, 접두사, 그리고 몹시 붐비는 하나의 이름 공간

WordPress 안의 PHP는 코어와 활성 테마, 그리고 활성화된 다른 모든 플러그인과 공유하는 단일 전역 이름 공간에서 실행됩니다. get_settings()라는 함수를 둘 다 선언하는 두 플러그인은 정중하게 양보하지 않습니다. 두 번째 것은 치명적 오류가 되고 사이트는 하얗게 변합니다.

접두사는 생각보다 길다

핸드북의 플러그인 모범 사례 문서는 전역에서 접근 가능한 모든 것에 고유한 접두사를 요구합니다. 최소 네 글자, 가능하면 다섯 글자, 흔한 영어 단어는 피하고 wp__, WordPress 자체는 절대 쓰지 말 것. 수만 개의 플러그인이 유통되는 상황에서 고객 이름 머리글자 세 개는 동전 던지기입니다.

이름 공간과 오토로딩

현대적인 방식은 문제의 절반을 해결합니다. PHP 이름 공간을 선언하고, 파일 하나에 클래스 하나를 두고, PSR-4 오토로더가 찾게 하십시오. 손으로 쓴 require 문이 사라지고 클래스 이름이 다른 플러그인과 충돌할 여지도 없어집니다. 코드를 시험하기도 쉬워집니다. 생성자로 의존성을 받는 클래스는 WordPress를 불러오지 않고도 만들 수 있기 때문입니다.

오토로딩이 해결하지 못하는 것은 두 플러그인이 같은 라이브러리의 서로 다른 버전을 함께 배포하는 경우입니다. 먼저 불린 쪽이 이깁니다. 배포하는 것이라면 빌드 시점에 벤더 이름 공간에 접두사를 붙이십시오.

이름 공간이 지켜 주지 못하는 문자열

이름 공간이 덮는 것은 PHP 심벌입니다. 플러그인이 등록하는 것의 상당수는 PHP 심벌이 아니라 공유 레지스트리에 놓이는 문자열이고, 그쪽에는 여전히 예전의 접두사 관습이 필요합니다. 훅 이름, 옵션과 트랜지언트 키, 게시물 메타 키, 게시물 타입과 분류 이름, 숏코드 태그, cron 이벤트 이름, REST 이름 공간, 그리고 직접 만든 테이블 이름입니다. 이들은 평평한 공간에 살면서 마지막에 등록한 쪽이 이기거나, 두 플러그인이 조용히 상태를 공유하게 됩니다.

무언가에 이름을 붙이기 전에 알아 둘 제한이 두 가지 있습니다. 게시물 타입 키는 20자를 넘을 수 없고 분류 키는 32자를 넘을 수 없으며, 둘 다 소문자 영숫자에 하이픈과 밑줄만 씁니다. 다섯 글자 접두사를 쓰면 게시물 타입 이름에 남는 것은 15자인데, 이는 들리는 것보다 훨씬 빠듯합니다.

데이터를 어디에 둘지 고르기

이것이 가장 오래 꼬리를 끄는 결정입니다. 잘못 고른 플러그인은 출시 시점에는 멀쩡히 동작하고, 데이터가 늘면서 매달 느려지고, 누군가 알아챌 무렵에는 고치는 일이 수정이 아니라 이전 작업이 되어 있습니다.

옵션과 트랜지언트

옵션은 사이트 전체 설정을 위한 것입니다. 키는 몇 개 되지 않고, 값은 작고, 대부분의 요청에서 읽힙니다. 함정은 자동 로딩입니다. 자동 로딩으로 표시된 옵션은 그것을 쓰든 안 쓰든 admin-ajax와 REST 호출을 포함한 모든 요청마다 가져와지기 때문입니다.

WordPress 6.6에서 그 동작이 바뀌었고, 큰 옵션의 자동 로딩 비활성화에 관한 Make WordPress Core 글이 그 내용을 정리하고 있습니다. 저장되는 값은 이제 on, off, auto 중 하나이고, 150,000바이트가 넘는 옵션은 기본적으로 자동 로딩되지 않으며, 그 기준값은 wp_max_autoloaded_option_size 필터로 조정할 수 있습니다. 그것은 목표가 아니라 천장이라고 여기십시오. 트랜지언트는 만료 시각이 있는 옵션이며, 바깥에서 가져온 것을 두기에 알맞은 자리입니다.

게시물 메타는 키값 저장소가 아니다

게시물 메타는 한 게시물의 속성을 위한 것입니다. 부제, 가격, 공급사 참조 번호 같은 것들입니다. 범용 키값 저장소가 아니며, 그 이유는 테이블 정의에 그대로 드러납니다. wp_postmeta 테이블에는 네 개의 열과 세 개의 키가 있습니다. 색인이 걸린 것은 post_idmeta_key의 앞 191자뿐입니다. meta_value 열은 longtext이고 색인이 전혀 없습니다.

따라서 메타 값으로 거르는 질의는 색인을 쓸 수 없습니다. 메타 질의의 조건이 하나 늘 때마다 조인이 하나 늘고, 게시물 50,000개가 각각 메타 20행을 달고 있는 사이트라면 테이블은 백만 행입니다. 조건이 셋이면 페이지를 열 때마다 백만 행을 상대로 조인을 세 번 합니다. 첫해에 빠르던 사이트가 3년째에 쓸 수 없게 되는 가장 흔한 이유 가운데 하나이고, WooCommerce 성능 작업에서 끊임없이 나타납니다.

커스텀 게시물 타입과 분류

커스텀 게시물 타입이 맞는 경우는 그 대상이 콘텐츠일 때입니다. 자체 목록 화면과 고유주소, 리비전, 편집 절차가 필요하고 누군가 방문할 수 있는 페이지로서 말이 될 때입니다. 커스텀 분류가 맞는 경우는 그것들을 묶는 공용 어휘가 필요하고 그 어휘가 자체 아카이브 페이지를 가질 만할 때입니다.

둘 다 기계 장치를 공짜로 데려옵니다. 관리 화면, 권한, 검색, 블록 편집기, 그리고 REST API입니다. show_in_rest를 true로 두지 않으면 블록 편집기가 그 타입을 다루지 못하고, 둘 다 init 훅에서 등록해야 하며 그보다 먼저 등록해서는 안 됩니다.

정말로 자체 테이블이 필요할 때

자체 테이블이 맞는 경우는 그 데이터가 콘텐츠가 아닐 때입니다. 이벤트 로그, 가져오기 대기열, 가격 이력, 감사 기록처럼 덧붙이기만 하는 대용량 기록이거나, 게시물 열에 없는 필드로 거르고 정렬할 것들입니다. 수십만 행을 넘고 자체 필드로 질의하는 규모가 되면, 색인을 제대로 건 테이블은 게시물 메타를 몇 자릿수 차이로 앞지르고 자라도 예측 가능하게 움직입니다.

대가는 전부를 직접 떠안는 것입니다. 테이블 생성과 버전이 붙은 이전 작업, uninstall.php에서의 정리, 자체 관리 화면과 REST 엔드포인트와 캐싱입니다. 그래서 대부분의 플러그인에 대한 솔직한 답은 여전히 커스텀 게시물 타입입니다.

보안은 네 가지 습관이고, 그중 셋이 빠진다

WordPress 보안 핸드북은 원칙을 분명히 말합니다. 사용자 입력도, 서드파티 API도, 이미 데이터베이스에 들어 있는 데이터도 믿지 말라는 것입니다. 위험의 거의 전부를 네 가지 습관이 짊어지는데, 우리가 감사하는 플러그인에서는 그것들이 일정한 순서로 빠져 있습니다. 권한 확인이 첫째, 논스가 둘째, 출력 이스케이프가 셋째입니다. 준비된 구문이 마지막인 것은 빠뜨리면 리뷰에서 걸리기 때문입니다.

권한 확인

무언가를 바꾸는 모든 처리기는 이 사용자에게 그것이 허용되는지 물어야 합니다. 다시 말해 current_user_can()에 구체적인 권한을 넘기고, 그것을 호출하는 버튼 주변이 아니라 처리기 안에서 확인해야 합니다.

is_admin()은 권한 확인이 아닙니다. 요청이 사이트의 어느 쪽에 들어왔는지를 알려 줄 뿐이고, admin-ajax 엔드포인트를 두드리는 로그인한 구독자에게도 true를 돌려줍니다. 권한 확인이 없는 admin_post_wp_ajax_ 액션은 등록된 모든 사용자가 닿을 수 있고, 쇼핑몰이라면 한 번이라도 주문한 모든 고객이 여기에 해당합니다. 이 주변의 사이트 수준 통제는 WordPress 보안 강화 체크리스트에서 다룹니다.

논스

논스는 사용자가 의도하지 않은 요청으로부터 양식이나 URL을 지킵니다. 양식에는 wp_nonce_field()를, 처리기에는 check_admin_referer()를, AJAX에는 check_ajax_referer()를 쓰십시오. 이름과 달리 한 번만 쓰이는 값이 아닙니다. 일정 시간 동안 유효한 해시이고, 기본값은 하루이며 두 칸으로 나눈 방식 때문에 실제 수명은 12시간에서 24시간 사이입니다.

논스 문서는 논스를 인증이나 인가, 접근 제어에 의지해서는 절대 안 된다고 분명히 말합니다. 논스가 세우는 것은 그 요청이 당신의 양식에서 왔다는 사실뿐입니다. 그 사람이 그 일을 해도 되는지에 대해서는 아무 말도 하지 않습니다.

들어올 때 정제하고 나갈 때 이스케이프한다

가능한 곳에서는 검증하십시오. 검증은 구체적이기 때문입니다. 우편번호는 형식에 맞거나 맞지 않거나 둘 중 하나입니다. 검증할 수 없는 곳에서는 정제하되, 항목에 따라 sanitize_text_field(), sanitize_email(), sanitize_key(), absint(), wp_kses_post() 가운데 하나를 씁니다.

그리고 출력하는 지점에서 매번 이스케이프합니다. esc_html(), esc_attr(), esc_url(), wp_kses_post() 중 하나입니다. 이스케이프 문서는 이것을 가능한 한 늦게 하라고 요구하는데, 그래야 검토하는 사람이 이스케이프와 출력을 같은 줄에서 볼 수 있기 때문입니다.

이스케이프는 다른 무엇보다 자주 빠집니다. 빠뜨려도 이상해 보이는 것이 없기 때문입니다. 누군가 입력란에 script 태그를 넣기 전까지 페이지는 완벽하게 표시됩니다.

준비된 구문

직접 작성한 질의는 모두 $wpdb->prepare()를 거칩니다. 정수에는 %d, 실수에는 %f, 문자열에는 %s, 테이블과 열 이름 같은 식별자에는 %i를 씁니다. 자리표시자는 따옴표로 감싸지 않고, 문자 그대로의 퍼센트 기호는 두 번 쓰며, LIKE 와일드카드는 질의문에 직접 적지 않고 치환 인자 안에 넣어 전달합니다. 변수를 SQL에 이어 붙이는 것은 취향의 차이가 아니라 그 자체로 취약점입니다.

REST API와 블록 편집기

올해 작성되는 플러그인이라면 데이터는 REST API로 노출하고 설정은 손으로 만든 옵션 페이지가 아니라 편집기를 통해 다루게 해야 합니다.

라우트는 rest_api_init 훅에서 register_rest_route()로 등록합니다. WordPress 5.5부터 permission_callback 인자가 필수이고, 빠뜨리면 해당 라우트를 지목하는 _doing_it_wrong() 알림이 뜹니다. 정말로 공개하려는 엔드포인트는 __return_true를 씁니다. 그것이 이 설계의 요점으로, 라우트를 공개로 만드는 일이 빠뜨림이 아니라 의도적으로 적은 한 줄이 됩니다. 커스텀 엔드포인트 문서는 인자 스키마도 다루는데, 정제와 검증 콜백은 거기에 두어야 잘못된 입력이 처리기까지 닿지 않습니다.

설정은 register_setting()으로 등록하고 show_in_rest를 true로 둡니다. 그러면 코어 설정 엔드포인트에 실리므로, 블록 편집기나 외부 스크립트가 인증과 권한과 검증을 이미 처리해 주는 인터페이스를 통해 읽고 쓸 수 있습니다. 옵션 페이지와 그 논스, 그 양식 처리기, 그리고 거기에 살던 버그들이 사라집니다.

블록은 block.json 파일에서 등록하며, WordPress 5.8부터 이것이 권장되는 정식 방법입니다. 블록 메타데이터 문서가 그 이점을 설명합니다. 거기에 선언된 자원은 플러그인이 활성화되어 있다는 이유로 사이트 전체에서 불리는 대신, 그 블록이 나타나는 페이지에서만 불립니다.

플러그인 안쪽의 성능 규율

감사에서 발견되는 플러그인발 지연의 대부분은 네 가지로 설명됩니다. 넷 다 피하기는 싸고 나중에 고치기는 비쌉니다. 첫째는 자동 로딩 옵션인데, 앞으로 모든 요청마다 값을 치르기 때문입니다.

둘째는 페이지가 열리는 동안 이루어지는 캐시 없는 원격 요청입니다. 공급사 API로 캐시 없이 보내는 wp_remote_get()은 모든 방문자가 그 공급사를 기다린다는 뜻입니다. 공급사가 느리면 사이트가 느려지고, 공급사가 죽으면 제한 시간이 끝날 때까지 사이트가 멈춰 있습니다. 응답은 트랜지언트에 캐시하고, 제한 시간을 명시하고, 호출이 실패했을 때 페이지가 무엇을 보여 줄지 미리 정해 두십시오.

셋째는 반복문 안의 질의입니다. 200행 각각에 get_post_meta()를 부르면 메타 캐시를 미리 채워 두지 않은 한 왕복이 200번이고, WP_Query는 맡겨 두면 그것을 대신 채워 줍니다. 고치는 방법은 대개 무언가를 끄는 일을 그만두는 것인데, 이는 Core Web Vitals 감사에서 나오는 대부분의 발견에도 그대로 적용됩니다.

넷째는 누군가의 페이지 요청 안에서 이루어지는 작업입니다. WP-Cron은 시스템 cron이 아닙니다. 페이지가 열릴 때 촉발되므로 예약 작업이 방문자의 요청 안에서 돌고, 한산한 사이트에서는 두 시에 돌 작업이 다섯 시에 누군가 방문할 때까지 돌지 않습니다. DISABLE_WP_CRON을 정의하고, wp-cron.php를 진짜 시스템 스케줄러로 돌리고, 작업은 짧고 몇 번 실행해도 결과가 같도록 유지하십시오.

코어 업데이트에서 살아남기, 아무도 예산에 넣지 않는 부분

코어가 무언가를 곧바로 지우는 일은 드뭅니다. 함수는 폐기 예정이 되고, 계속 동작하고, 알림을 냅니다. 그래서 WP_DEBUG를 켠 스테이징 환경을 돌리는 것이 구할 수 있는 가장 값싼 조기 경보 장치입니다. 폐기 예정 알림은 아직 싸게 고칠 수 있을 때 고치라는 날짜가 적힌 초대장입니다.

뜻밖의 사고를 막는 절차는 분기에 한 시간쯤 듭니다. 코어 개발 블로그를 따라가며 베타와 릴리스 후보가 언제 나왔는지 파악하십시오. 릴리스 후보 시기에 나오는 필드 가이드를 읽으십시오. 거기에 그 릴리스의 개발자용 기능과 호환성을 깨는 변경이 정리되어 있습니다. 그런 다음 릴리스 후보를 스테이징 사본에 올리고, 플러그인의 실제 기능을 적어 둔 점검 목록대로 훑으십시오.

지원 버전은 코드만큼 중요합니다. WordPress가 요구하는 PHP는 절대 하한이 7.4이고 권장은 8.3 이상이며, 함께 MariaDB 10.11 또는 MySQL 8.0을 요구합니다. 플러그인 헤더의 Requires PHPRequires at least를 정직하게 적고, 개발자 노트북에서 도는 버전이 아니라 스스로 선언한 가장 낮은 버전에서 시험하십시오.

자기 플러그인에는 유의적 버전을 붙이고 그 뜻을 지키십시오. 패치는 무언가를 고치고, 마이너는 아무것도 깨지 않으면서 동작을 더하고, 메이저는 깨도 되지만 무엇을 깼는지 밝혀야 합니다. 자동 업데이트를 켜 둔 고객은 그 약속에 기대고 있습니다.

배포와 라이선스, 그리고 업데이트가 사이트에 닿는 방법

WordPress는 GPL 버전 2 이상으로 배포되고, wordpress.org 라이선스 페이지는 플러그인과 테마가 그 라이선스를 물려받는 파생 저작물이라는 프로젝트의 입장을 밝히면서, 무엇이 파생 저작물인지에 대해 법적으로 회색 지대가 있다는 점도 인정합니다.

소스는 언제나 받게 되고, 그것을 고칠 다른 누구든 고용할 수 있습니다. GPL이 하지 않는 일은 그것을 공개하도록 강제하는 것이어서, 한 회사를 위해 만든 플러그인은 비공개로 남을 수 있습니다. 또한 개발자가 같은 결과물을 다른 사람에게 파는 것도 막지 않습니다. 독점이 중요하다면 그것은 라이선스 조항이 아니라 계약 조항입니다.

플러그인을 공개 디렉터리에 올린다면 플러그인 디렉터리 지침 18개를 만족해야 합니다. 첫 번째 항목은 이미지까지 포함해 패키지 안의 모든 것에 GPL과 호환되는 라이선스를 요구합니다. 다른 항목들은 결제나 업그레이드 뒤에 기능을 잠그는 체험판 방식을 배제하고, 난독화된 코드를 금지하고, 동의 없이 사용자를 추적하는 것을 막고, 허락 없이 공개 사이트에 링크나 크레딧을 붙이는 것을 금합니다.

비공개로 남긴다면 업데이트는 당신의 문제가 됩니다. Update URI 헤더를 설정하십시오. 이 헤더는 비공개 플러그인이 이름이 비슷한 디렉터리의 플러그인으로 덮어써지는 것을 막으려고 존재합니다. 그리고 업데이트는 당신의 엔드포인트에서 배포하십시오. 이 일을 끝으로 미루면 고객이 FTP로 업데이트하는 처지가 됩니다.

맞춤형 WordPress 플러그인의 비용

아래 구간은 여기에서 설명한 기준으로 납품되는 작업에 대한 영국 에이전시의 GBP 가격입니다. 즉 테스트와 문서가 있고, 출시 이후 책임지는 담당자가 정해져 있는 상태를 말합니다. WordPress와 PHP를 다룰 수 있는 개발자는 하루에 대략 £400에서 £600을 청구하므로, 이 숫자들은 단가가 아니라 범위에 대한 이야기입니다.

작은 유틸리티 플러그인은 £1,500에서 £3,000입니다. 하는 일은 하나, 훅은 몇 개, 설정 토글이 하나 있을까 말까 한 수준입니다. 리디렉션 처리, 주문에 항목 하나 추가, 공급사로 보내는 야간 내보내기 같은 것들입니다.

중간 규모 연동은 £3,000에서 £15,000입니다. 인증과 재시도와 오류 처리가 붙은 서드파티 API, 커스텀 게시물 타입, 관리 화면, 그리고 뒤에서 도는 처리입니다. 가장 많이 발주되는 규모이자 가장 자주 과소 추정되는 규모인데, 연동 자체는 일주일이고 실패 처리가 이 주일이기 때문입니다.

본격적인 제품형 플러그인은 £20,000에서 £75,000이거나 그 이상입니다. 자체 테이블, 블록 편집기 화면, 라이선스와 업데이트 기반, 멀티사이트 지원, 그리고 출시하는 날부터 시작되는 지원 부담이 따라옵니다.

낮은 쪽 가격을 치르는 것이 자동으로 잘못은 아닙니다. 잘못이 되는 경우는 그 가격이 아래의 산출물을 슬그머니 뺀 범위에서 나왔을 때입니다. 견적을 읽는 법은 WordPress 개발자 단가와 물어볼 것들 안내에서 다루고, 우리가 이 작업의 범위를 어떻게 잡는지는 WordPress 개발 페이지에 적어 두었습니다.

산출물에 들어 있어야 할 것

아래 항목은 모두 착수 전에 문서로 요구하십시오. 하나같이 포함시키기는 싸고 나중에 더하기는 비쌉니다. 먼저 소스입니다. 마지막 날 메일로 오는 zip 파일이 아니라, 당신이 소유한 저장소에 이력이 온전히 남은 형태여야 합니다. 그리고 업무 규칙에 대한 단위 테스트와, 데이터베이스에 쓰거나 외부 서비스를 부르는 모든 것에 대한 통합 테스트입니다. 그것이 있어야 2년 뒤에 그 자리에 없던 누군가가 안심하고 고칠 수 있습니다.

또 리드미가 필요합니다. 플러그인이 무엇을 하는지, 무엇에 훅을 거는지, 무엇을 어디에 저장하는지, 어떤 외부 서비스를 부르고 그 각각이 실패하면 무슨 일이 벌어지는지 적힌 문서입니다. 두 쪽이면 충분하고, 이것이 없다는 사실이야말로 플러그인이 유지되지 못하고 교체되는 이유입니다. 옵션과 테이블, cron 이벤트와 메타를 지우는 uninstall.php도 필요합니다. 그리고 코어 릴리스마다 시험하고 그 시험에서 나온 것을 고치는, 담당자가 정해진 지원 계약이 필요합니다.

만들게 하기

Mecanik은 위 세 규모 모두에서 플러그인을 만들고, 다른 사람이 작성한 플러그인을 넘겨받기도 하는데 후자가 더 쓸모 있는 경우가 많습니다. 우리가 범위를 어떻게 잡고 어떻게 납품하는지는 WordPress 개발자소프트웨어 개발 페이지에서 설명합니다. 이미 아무도 손대고 싶어 하지 않는 플러그인이 있다면, 위 관행에 비추어 보는 감사에는 하루쯤 걸리고 그것이 고칠 수 있는 것인지 갈아엎을 것인지 알려 줍니다.



자주 묻는 질문

맞춤 기능은 플러그인에 넣어야 하나요, 테마에 넣어야 하나요? 순수하게 표현에 관한 것이 아니라면 플러그인입니다. 테마는 다음 리뉴얼에서 교체되고 그 테마가 하던 일은 전부 멈춥니다. 커스텀 게시물 타입은 관리 화면을 잃고, 숏코드는 날것의 문자열로 표시되고, 연동은 조용히 돌지 않게 됩니다. 리뉴얼 이후에도 여전히 참이어야 하는 것은 모두 플러그인에 속합니다.

영국에서 맞춤형 WordPress 플러그인을 만들면 비용이 얼마나 드나요? 작은 유틸리티 플러그인은 보통 £1,500에서 £3,000, 서드파티 API와 관리 화면이 붙은 중간 규모 연동은 £3,000에서 £15,000, 자체 테이블과 업데이트 기반을 갖춘 본격적인 제품형 플러그인은 £20,000에서 £75,000 이상입니다. 이런 작업을 해낼 수 있는 개발자는 하루에 대략 £400에서 £600을 청구합니다.

WordPress 코어나 다른 플러그인의 파일을 고쳐도 괜찮은 경우가 있나요? 없습니다. 그 수정은 다음 업데이트에서 지워지고, 오류도 나지 않으며, 대개는 무언가가 멈출 때까지 아무도 알아채지 못합니다. 대신 액션과 필터를 쓰십시오. 필요한 훅이 없다면 동작을 감싸거나, 버전 관리 아래에서 플러그인을 포크하거나, 상류에 훅을 추가해 달라고 요청하십시오.

돈을 주고 만들게 한 플러그인은 제 것이 되나요? 당신의 사본과 계약에 적힌 것이 당신 것입니다. GPL은 소스와 그것을 고칠 권리, 그리고 다른 누구에게든 유지보수를 맡길 권리를 주지만 공개를 요구하지는 않으므로, 한 회사를 위해 만든 플러그인은 비공개로 남을 수 있습니다. 개발자가 같은 결과물을 다시 파는 것은 막지 못하므로, 독점이 중요하다면 계약에 넣으십시오.

WordPress가 업데이트될 때 플러그인이 깨지지 않게 하려면 어떻게 하나요? 그 버전이 배포되기 전에 스테이징 사본에서 모든 릴리스 후보를 상대로 시험하고, WP_DEBUG를 켠 스테이징을 돌려 폐기 예정 알림이 일찍 드러나게 하고, 플러그인이 지원하는 PHP와 WordPress 버전을 헤더에 선언하십시오. WordPress는 PHP 7.4를 하한으로 요구하고 8.3 이상을 권장합니다.