예전에 본문에서 카테고리 제목을 표시할 때 상위 카테고리의 제목도 같이 출력하는 팁을 쓴 적이 있었는데요.

이번에 빵조각 애드온이라는 걸 배포하면서 관련 팁을 좀 더 업그레이드해봤습니다.

카테고리 정보가 3차, 4차 분류에 속하더라도 1차 분류까지 소급해서 모든 상위 카테고리의 정보를 받아오는 방법입니다.

다만, 재귀함수를 사용해야 해서 게시판 스킨에서 php 함수를 정의할 수 있는 상황이 아니라면, 애드온이나 위젯 같은 다른 서드파티 자료들에서 사용하는 게 적절하다는 점을 고려하시면 좋을 듯합니다.

 

빵조각 애드온에서 사용한 소스 코드를 중심으로 설명해보도록 하겠습니다.

 

1. 먼저 함수를 선언해둡니다.

// $mid는 카테고리가 소속된 mid값
// $category는 url 쿼리스트링의 category값 또는 문서 객체($oDocument)가 가지고 있는 category_srl값
// $category_list는 해당 모듈의 카테고리 목록(보통 캐시로 활용됨)
// $show_upper_category는 빵조각 애드온에서 설정된 상위 카테고리 표시 여부 변수값
// $category_info는 본 재귀함수에서 반환할 배열 변수
// 이 인자를 누락하거나 빈 배열을 전달하면 $category_info에는 최종 차수의 카테고리부터 1차 카테고리까지 관련 데이터가 차곡차곡 쌓이게 됨
function getCategoryInfo($mid, $category, $category_list, $show_upper_category = 'Y', $category_info = array())
{
    // 여기서는 반환받을 카테고리 정보 변수에 링크 주소와 제목만 담음
    $category_info[$category] = new stdClass();
    $category_info[$category]->href = getUrl('', 'mid', $mid, 'category', $category);
    $category_info[$category]->title = $category_list[$category]->title;

    // 애드온에서 상위 카테고리를 표시하기로 한 경우에만 재귀함수 적용
    // 현재 함수로 전달된 $category의 분류 depth가 0이 될 때까지(즉 1차 분류에 도달할 때까지) 재귀함수가 돌아감
    if ( $category_list[$category]->depth && $show_upper_category !== 'N' )
    {
        // 여기서는 $category가 아니라 상위 카테고리 번호($category_list[$category]->parent_srl)를 함수 getCategoryInfo에 전달함
        return getCategoryInfo($mid, $category_list[$category]->parent_srl, $category_list, $show_upper_category, $category_info);
    }
    else
    {
        // 카테고리의 depth가 0에 도달하면 상위 카테고리의 정보를 담은 $category_info를 반환함
        // 다만 여기서는 $category_info의 배열 순서가 4-3-2-1처럼 역순으로 담기게 되므로 배열 순서를 뒤집어서 반환
        return array_reverse($category_info, true);
    }
}

 

 

2. 이제 이 함수를 호출해서 상위 카테고리가 포함된 카테고리 정보를 반환받아 담을 수 있습니다.

$breadcrumb_info->category_info = getCategoryInfo($module_info->mid, $category, $category_list, $addon_info->show_upper_category);

debugPrint($breadcrumb_info->category_info)를 찍어보면, 이렇게 나옵니다.

Array ( [23845] => stdClass Object ( [href] => /devlog/category/23845 [title] => EXAM ) [23849] => stdClass Object ( [href] => /devlog/category/23849 [title] => Bug Fix ) )

배열의 첫 번째 원소가 1차 분류이고, 두 번째 원소가 2차 분류입니다ㅎ

 

 

3. 그리고 이 변수를 html 템플릿 등에 잘 전달한다면, 이런 식으로 사용해볼 수 있습니다.

<!--@foreach($breadcrumb_info->category_info as $category_srl => $category_info)-->
    <a href="{$category_info->href}">{$category_info->title}</a>
<!--@endforeach-->

 

 

4. 관련 예시입니다 :) https://dev.aporia.blog/devlog/category/23849

 

이상 노트 겸 팁 정리였습니다 :)

윤삼

profile
아무래도 중급 초반 수준의 코딩 오타쿠인 것 같습니다.
  • profile
    역시 정리잘하시는 윤삼님 오늘도 굿굿굿~
  • profile profile
    기록 차원에서 남겨봤어요 ㅎㅎㅎ
  • profile
    function_exists 를 쓸필요 없이 독립적인 함수이름을 써서 함수를 선언하시기 바랍니다.

    function_exists를 통해서 이미 함수가 나와있다면 그건 이미 다른 역할을 담당할수있는 항목이니.. 그렇다고 애드온에서 원하는 동작을 다르게 만들어 버릴 수 있잖아요

    그래서 그렇게 만드시면 function_exists도 쓸필요가 없을듯하네요 ㅎㅎ
  • profile profile
    이게 애드온에서 쓴 예시인데, 호출 시점에 따라 중복 선언되는 경우가 있어서 그걸 회피하려고 한 거였어요.
    다른 경우에서 함수를 사용할 때는 당연히 확인을 거칠 필요는 없지만, 중복이 일어나면 에러를 뿜더라구요.
  • profile profile

    라이믹스 기준 호출시점은 3곳이지요...

     

    실제로 애드온이 실행될 항목은 1곳아닌가요?

     

    그럼 1곳에 접속할때에만 해당 함수를 선언해서 같이 쓰면됩니다.

     

    붙여넣은_이미지_2022_4_6_오후_9_53.png

    test.php

     

    붙여넣은_이미지_2022_4_6_오후_9_54.png

    testhome.php

     

    실제출력값 : 1test

     

    실제로 애드온은 php으로만 이루어진 include 형태로 호출되니까 실제로 지정한 호출이 아니면 두번 이상 호출 하지 않게끔 만들어주면 될거예요

     

    한번 알아보세요

     

    어차피 기능을 보기엔 하나의 호출시점에서 모든 작업을 다 하게 될텐데 굳이 여러 호출점을 다잡고 저 기능을 동작 시켜줄 필요가 없거든요.

     

    제일 마지막이라도 그때 애드온이 로딩되었을때 해당 함수를 호출할 수 있도록 include시켜주도록 해보세요.

  • profile profile
    이런 꼼수를 가르쳐주지 말고, 이번에는 모듈을 만드시도록 꼬셔 보아요! ㅋㅋㅋㅋ
  • profile profile
    갑 of 갑은 모듈이죠.. 모듈의 세계로 한번 오시죠? @윤삼

    다이아도 달으셧는데 ㅋㅋㅋ
  • profile profile

    if ( $called_position !== 'before_display_content' || Context::getResponseMethod() !== 'HTML' || Context::get('module') === 'admin' )
    {
    return;
    }
    이렇게 하고 그 '뒤'에 함수를 선언해서 중복 선언 오류가 났었는데,

    if ( $called_position === 'before_display_content' && Context::getResponseMethod() === 'HTML' && Context::get('module') !== 'admin' )
    조건을 이렇게 바꾸고 이 '안'에서 함수 선언하고 진행했더니 오류가 안 나네요.

    두 조건 사이에 무슨 차이가 있는 것인지 흠...
    암튼 말씀하신대로 조건문은 잘 제거하게 됐습니당 :D

  • profile profile
    모듈로 갈 거예욧. 꼭 갈 거라구욧!
  • profile profile
    $called_position !== 'before_display_content' 이게 문제네요. 두번실행하겠네요.
  • profile profile

    아! 이 부분만 딱 짚어주시니까 깨달음이 왔습니다.

    왜 그게 머리에 안 들어왔는지 허허...
    언제나 감사해요ㅜㅜ

  • profile
    오옹 이런것도있군요!! 좋은자료감사합니다~~
  • profile profile

    메뉴가 많고 복잡한 사이트에서 길을 잃지 않을 수 있도록 도와주지요. 빵조각ㅎㅎ

  • profile profile
    역시 라이믹스의 길잡이.. 윤삼님..!