이중 외부 상품은 사이트 외부의 상품을 단순 링크할 뿐 장바구니를 이용하지 않으므로 노트할 대상에서 제외된다. 그러면 나머지 상품들이 싱글 페이지 폼에서 어떻게 처리되는지 노트한다. 상점의 테마는 storefront를 사용했다.
폼 핸들러
우선 폼 핸들러에 대해 노트. 상품을 장바구니에 담는 행위는 상품 싱글 페이지에서 사용자가 선택한 상품과 그 갯수를 폼을 통해 전송하는 것으로 구현한다. 이 때 폼을 전송하는 서버의 URL은 해당 페이지와 동일하다.
한편 우커머스는 ‘wp_loaded‘ 액션의 콜백으로 WC_Form_Handler::add_to_cart_action() 을 등록한다. 우커머스 플러그인 디렉토리 includes/class-wc-form-handlers.php에 위치해 있으며, 여기서 각 상품의 타입에 따라 각각 다른 세부 폼 핸들러에 대응하도록 구현되어 있다.
폼에서 상품 ID를 인지하려면 반드시 폼에 ‘add-to-cart’ 변수가 설정되어 있어야 한다. 그래야 핸들러가 제대로 동작한다.
기본상품
가장 간단한 상품 구조이다. 단일 상품에 대해 갯수만 선택하면 장바구니에 담긴다. 이것의 폼 구조는,
키
값
add-to-cart
정수. 상품의 ID.
quantity
정수. 상품의 개수.
옵션상품
대체적으로 같은 상품이지만, 상품의 여러 속성에 따라 각자 조금씩 하위 분류로 구분되는 상품들이다. 옷들이 옵션 상품이 될 수 있는 대표적인 상품이다. 한 상품의 색상, 사이즈에 따라 구분되는 것.
다른 상품으로 상점 관리에서 미리 상품에 대한 여러 속성을 정의하면, 그 속성의 조합에 따라 미리 하위 상품을 만들어 둔다. 예를 들어 옷의 색상이 흰색, 검정, 2가지가 있고 옷의 사이즈는 소, 중, 대로 3가지가 가능하다고 하자. 그러면 옵션 상품의 하위 상품(variation)으로 총 2×3, 6개가 생성된다. 이 하위 상품은 각자 가격, SKU, 재고, 무게나 크기 같은 상품 정보를 다르게 취할 수도 있다.
키
값
attribute-{$attribute}
문자열. 사용자가 선택한 속성값이다. $attribute는 속성값을 의미한다. 위 그림에서 ‘색상’에 해당한다. 한글의 경우 URL Encode 된다. 예를 들어 ‘색상’은 ‘%ec%83%89%ec%83%81’로 인코드된다.
quantity
해당 상품의 수량
add-to-cart
옵션 상품의 ID와 동일하다. 핸들러는 여기서 기준이 되는 상품 ID를 캐치한다.
product_id
옵션 상품(variable)의 ID. 결국 add-to-cart 값과 동일하다.
variation_id
사용자가 선택한 속성에 해당하는 하위 집합의 상품 ID 중 하나. 폼 핸들러에서 사용하는 값은 이 쪽이다.
우커머스는 현재 옵션 상품의 옵션을 설정해 한 번에 하나의 하위 상품만을 장바구니에 담는 것만이 가능하다. 다시 말해 옷을 구매할 때, 검정-소 사이즈를 설정한 다음 장바구니에 넣고, 다시 페이지로 돌아와 흰색-중 사이즈를 설정해 장바구니에 넣어야 한다. 검정-소와, 흰색-중 이 두 조합을 한 번에 선택한 다음 한 번에 장바구니에 넣을 수는 없다.
그룹상품
그룹 상품은 몇 개의 상품을 하나로 묶어 한 페이지에서 동시에 여러 상품을 구매할 수 있도록 한다. 연결된 상품이라고 해서 동시에 구매했을 때 할인이 주어지게 하는 옵션은 기본적으로는 없는 것 같다. 단지 몇 개의 상품을 한 페이지에서 한번에 장바구니로 넣게 해주는 것일 뿐.
키
값
qty
연관 배열. 키는 선택된 상품의 ID. 값은 해당 상품의 개수.
add-to-cart
그룹 상품의 ID.
기타
장바구니 추가 로직에서 딱히 강한 제약은 없다. 폼의 구조만 틀리지 않는다면, 폼의 정보는 싱글 페이지와 무관하다. 가령 48번 상품 싱글 페이지에서 값을 강제로 변경해 50번 상품으로 만들어 장바구니에 담아도, 50번 상품의 상태만 올바르다면 막히는 것이 없다.
또한 폼의 내용은 마음대로 확장할 수 있고, 확장된 폼의 내용은 적절히 폼 핸들러의 동작을 커스텀하여 처리하면 된다.
멀티 사이트는 여러 워드프레스 사이트를 하나의 설치본으로 관리할 수 있게 한다. 이렇게 만들면 데이터베이스에는 추가적으로 테이블이 생기게 된다.
이 중 wp_blogs, wp_site 가 눈에 뜨인다. 보통 멀티사이트를 만들면 wp_blogs 에는 멀티로 만든 사이트 목록이 기록된다. 그리고 wp_site는 주로 단일 레코드가 기록될 것이다.
그런데 wp_site의 레코드를 통해 멀티사이트의 확장이 가능하다. 즉, 하나의 워드프레스 설치본으로 멀티사이트를 여러 개 만드는 것까지 가능하다는 소리다. 즉 이런 계층구도가 생성된다.
멀티사이트 #1
사이트 #1-1
사이트 #1-2
멀티사이트 #2
사이트 #2-1
사이트 #2-2
이렇게 하려면 데이터베이스에 여러 레코드를 편집하면 되는데, 편집해야 할 양이 좀 많아 관리하기 까다롭다. wp_site, wp_blogs, {prefix}_{blog_id}_* 테이블을 괸리해야 하기 때문이다. 이 정도는 WP Multi Network 플러그인에게 맡기는 것이 좋을 것 같다. 멀티사이트 관련 API에 큰 변동이 없어 그런지 이 플러그인은 현재도 잘 동작한다.
네트워크까지 관리할 수 있다.DB는 이렇다. 네트워크 사이트가 하나 더 생겼다.site_id가 3인 녀석이 등장했다.
훅 기능은 워드프레스에서 구현한 기능이며 일반적인 자바스크립트가 아니지만, 카테고리를 간결하게 유지하고 싶어 이 곳에 작성한다.
PHP에서 작성된 add_action, add_filter 같은 훅 제어가 JavaScript에서도 아주 유사하게 작성되어 있다! 자바스크립트가 비동기 방식이고, 이벤트 핸들링을 위해 콜백 함수를 쓰는 것이 매우 일상적이긴 하지만, 자바스크립트 고유의 콜백 방식을 쓰기는 조금 난감할 때가 있는데, 이 패키지를 사용하면 문제 없이 훅을 다룰 수 있다.
리포지터리에 이 혹을 사용해 보는 코드를 작성해 봤다. 아주 간단하게 자바스크립트에서 액션과 필터가 동작하는 코드이다. 기대되는 동작은 기존에 사용하던 PHP 쪽 버전과 동일하게 동작하기 때문에 사용하는 법만 대충 테스트하면 충분할 듯하다.
예제를 위해 슬러그가 ‘hooks-test’인 포스트를 생성한다. 스크립트는 이 포스트에서만 동작하도록 처리했다. 결과는 아래 그림과 같다.
다 같은데, 두번째 인자가 네임스페이스라는 점이 다르다. 이 네임스페이스는 hasFilter(), hasAction() 체크시에 사용되는 것 외에는 크게 의미는 없다. 저걸 다르게 준다고 해서 doAction, applyFilters 함수 호출시 특별한 동작을 하게 되는 것은 아니다. 즉 네임스페이스가 다르되, 훅 이름이 같다 하더라도 각 훅이 구분되는 일 따위가 없을 것이다.
아무튼 이 훅 관련 함수는 이미 코어 여러 부분에 적용되어 있다. 응용하면 자바스크립트에서 그동안 아쉬웠던 훅을 통한 기능 수정이 편안하게 될 수 있으리라 기대한다.