본문으로 건너뛰기
TubePress — 무료, 자체 호스팅 & 지속 관리
개발자 레퍼런스

훅 및 플러그인 개발

WordPress 스타일의 액션 및 필터 훅 시스템으로 TubePress를 확장하세요. 15개 이상의 훅 포인트, 플러그인 라이프사이클, 그리고 직접 플러그인을 만들고 패키징하는 방법을 다룹니다.

플러그인은 코어를 건드리지 않고 TubePress에 기능을 추가하는 방법입니다. 플러그인은 소규모 WordPress 스타일의 액션(발생 후 잊는 이벤트)과 필터(값을 수정하고 반환) 시스템을 통해 CMS에 연결됩니다. 함께 제공되는 세 가지 플러그인 — Age Gate, Backup Pro, CTR Ranking — 은 여기에 문서화된 동일한 API로 완전히 구축되었습니다.

훅 시스템

정적 HookSystem 클래스는 두 종류의 훅을 모두 관리합니다. 콜백은 오름차순 우선순위(기본값 10)로 실행되며, 콜백이 던지는 예외는 캐치되어 로그에 기록되므로 불량 플러그인 하나로 인해 페이지가 다운되는 일은 없습니다.

// Actions — do something when an event fires
HookSystem::addAction('head.meta', function () {
    echo '<meta name="rating" content="adult">';
}, 10);

// Filters — receive a value, return a (possibly) changed value
HookSystem::addFilter('theme.template_data', function ($data, $template) {
    if ($template === 'home') {
        $data['promo'] = Promo::current();
    }
    return $data;
});
메서드용도
addAction($hook, $cb, $priority = 10)액션 리스너를 등록합니다.
doAction($hook, ...$args)액션을 실행합니다(코어에서 호출).
addFilter($hook, $cb, $priority = 10)필터를 등록합니다.
applyFilter($hook, $value, ...$args)값을 필터에 통과시키고 반환합니다.
hasAction() / hasFilter()리스너가 있는지 확인합니다.
removeAction() / removeFilter()훅의 모든 리스너를 분리합니다.

사용 가능한 훅 포인트

코어는 이러한 훅을 실행합니다. 플러그인에서 직접 정의하고 실행할 수도 있습니다.

액션

실행 시점
head.meta<head> 내부, CSS 이후 — 메타 태그, 인증 태그 등을 추가합니다.
footer.scripts</body> 이전, JS 이후 — 분석 도구나 위젯을 추가합니다.
routes.registered모든 코어 라우트가 등록된 후, 페이지 catch-all 이전.
router.before_dispatch매칭된 핸들러가 실행되기 직전. 인수: 확인된 경로.

필터

수정 대상 (인수)
theme.template_data템플릿이 렌더링되기 전의 데이터 배열. 인수: ($data, $templateName).
head.css결합된 CSS 출력 문자열.
footer.scripts결합된 JS 출력 문자열.
video.card.html전체 비디오 카드 HTML. 인수: ($html, $video). 비어 있지 않은 문자열을 반환하면 대체됩니다.

플러그인 구조

플러그인은 plugins/ 아래의 폴더로, 매니페스트와 PluginInterface를 구현하는 클래스로 구성됩니다.

plugins/myplugin/
├── plugin.json     Manifest (name, slug, version, …)
├── myplugin.php    Main class implementing PluginInterface
├── icon.svg        Optional icon shown in the admin
└── …               Your assets, templates, migrations

매니페스트는 번들 플러그인과 동일한 형식입니다:

{
  "name": "My Plugin",
  "slug": "myplugin",
  "description": "What it does, in one sentence.",
  "version": "1.0.0",
  "author": "You",
  "requires": "1.0.0",
  "icon": "icon.svg"
}

메인 클래스는 PluginInterface의 6가지 수명 주기 메서드를 구현합니다:

메서드호출 시점
boot()플러그인이 활성화된 상태의 모든 요청 시 — 여기서 훅, 라우트, 에셋을 등록합니다.
activate()관리자가 플러그인을 활성화합니다.
deactivate()관리자가 비활성화합니다.
install()최초 활성화 시 — 테이블 생성, 설정 시드.
uninstall()플러그인 제거 시 — 정리 작업을 수행합니다.
info()매니페스트 데이터를 배열로 반환합니다.

라우트 및 에셋 등록

boot()에서 모든 연결 설정을 수행합니다:

public function boot(): void
{
    // A front-end route
    Router::get('/promo/{code}', [PromoController::class, 'show']);

    // Inject a meta tag
    HookSystem::addAction('head.meta', [$this, 'meta']);

    // Tweak every video card
    HookSystem::addFilter('video.card.html', [$this, 'badge'], 20);
}
설계상 자기 완결적입니다. 플러그인은 자체 스키마, 설정, 라우트, 관리 페이지, 예약 작업 등 필요한 것을 모두 추가하고, 제거 시 다시 정리해야 합니다. 기본 CMS에는 변경이 없어야 합니다. CTR Ranking 플러그인이 좋은 예입니다.

플러그인의 예약 작업

boot()에서 CronManager를 통해 반복 작업을 등록합니다. 내장 pseudo-cron으로 실행되므로 시스템 crontab이 필요하지 않습니다. CTR 플러그인의 점수 재계산 및 Backup Pro의 예약 백업이 이 방식으로 동작합니다.

번들 플러그인 참조

배포 및 라이선스

플러그인을 비공개로 유지하거나, 자유롭게 공유하거나, 마켓플레이스를 통해 판매할 수 있습니다. 마켓플레이스는 서명된 라이선스와 도메인별 활성화를 지원합니다. 프레젠테이션 측의 동등한 기능은 테마 개발을 참조하고, 템플릿 코드에서 사용 가능한 모든 것은 테마 API 참조를 확인하세요.

여전히 막히셨나요?

대시보드에서 티켓을 열면 저희 팀이 도와드리겠습니다.

라이브 데모 체험하기 → TubePress 다운로드 →