워드프레스 자식 테마에서 함수 오버라이드 문제

2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이미지가 포함된 트윗을 제대로 보여주지 못한다. 테마 제작사에 이메일도 보내봤지만 영어를 잘 못해서인지 수정이 되지 않아서 방법을 찾기로 했다.

처음에는 스타일시트에서 div 태그를 재정의하려고 했으나 잘 안 되어서, 아예 function.php에서 관련 필터 함수를 찾아서 수정을 하려 했다. 그런데 사용중인 테마의 스타일시트나 php 페이지를 직접 수정하면 테마를 업그레이드할 때 수정된 부분이 덮어써질 수 있다. 그래서 수정된 부분을 백업해둬야 하고, 테마를 업그레이드하고 나면 재적용해야 하는 불편함이 있다. 그럴 때 유용한 것이 자식 테마(child theme)이고, 관련된 내용은 워드프레스 코덱스의 자식 테마 항목을 참고하면 된다. 자식 테마를 쓰면, 부모 테마에서 필요한 기능을 추가하거나 재정의할 수 있다.

그런데 자식 테마에서 스타일시트는 재정의(override, 덮어쓰기)가 가능한데, functions.php의 함수는 재정의가 안 된다. 그래서 검색을 하다보니 필터의 경우, 기존 필터 적용을 해제하고 새로운 필터를 적용하는 식으로 구현을 할 수 있다는 걸 알게 되었다. 

우선 Hueman 테마(부모 테마)의 function.php에서 임베드 필터와 관련된 내용은 아래와 같다.

/*  Add responsive container to embeds
/* ------------------------------------ */
if ( ! function_exists( 'alx_embed_html' ) ) {

        function alx_embed_html( $html ) {
                return '
' . $html . '
'; } } add_filter( 'embed_oembed_html', 'alx_embed_html', 10, 3 ); add_filter( 'video_embed_html', 'alx_embed_html' ); // Jetpack

아래는 자식 테마의 functions.php다.

/*  Function: Modify alx_embed_html(in parent theme) */
/* ----------------------------------------- */
if ( ! function_exists( 'alx_embed_html_raftwood' ) ) {

        function alx_embed_html_raftwood( $html ) {
                if ( strpos( $html, "twitter-tweet" ) !== false )
                   { return $html; }
                else
                   { return '
' . $html . '
'; } } } /* Function: Remove filters in parent theme and add new filters */ /* -------------------------------------------------------------- */ if ( ! function_exists( 'my_child_theme_setup' ) ) { function my_child_theme_setup( ) { remove_filter( 'embed_oembed_html', 'alx_embed_html', 10, 3 ); remove_filter( 'video_embed_html', 'alx_embed_html' ); // Jetpack add_filter( 'embed_oembed_html', 'alx_embed_html_raftwood', 10, 3 ); add_filter( 'video_embed_html', 'alx_embed_html_raftwood' ); // Jetpack } } /* Add action: Above function after setup theme */ /* ---------------------------------------------- */ add_action( 'after_setup_theme', 'my_child_theme_setup' );

처음에 정의된 alx_embed_html_raftwood 함수는, 부모 테마의 alx_embed_html 함수를 수정한 것이다. 임베드한 내용에 ‘twitter-tweet’이라는 문구가 들어가 있으면 div 태그로 감싸지 않게 했다. 이어지는 my_child_theme_setup은 기존 필터를 지우고 새로운 필터를 추가하는 함수다. 마지막으로 add_action으로 테마가 셋업 이후(after_setup_theme)에 my_child_theme_setup 함수를 실행하도록 했다.

filter가 아닌 action에 쓰이는 함수도 위와 유사한 방식으로 바꿀 수 있을 것이다. 다음에 적용할 일이 있으면 다시 한 번 정리해 보겠다.

뗏목지기: 만화를 좋아하고 세상 돌아가는 일에 관심이 많은 평범한 직장인입니다.

View Comments (0)