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

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

Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /volume1/web/www/blog/wp-content/plugins/wp-syntax/wp-syntax.php on line 380 Call Stack: 0.0000 360448 1. {main}() /volume1/web/www/blog/index.php:0 0.0000 360752 2. require('/volume1/web/www/blog/wp-blog-header.php') /volume1/web/www/blog/index.php:17 0.4648 16540128 3. require_once('/volume1/web/www/blog/wp-includes/template-loader.php') /volume1/web/www/blog/wp-blog-header.php:19 0.4683 16597824 4. include('/volume1/web/www/blog/wp-content/themes/oceanwp/singular.php') /volume1/web/www/blog/wp-includes/template-loader.php:106 0.6687 18055288 5. get_template_part($slug = 'partials/single/layout', $name = 'post', $args = ???) /volume1/web/www/blog/wp-content/themes/oceanwp/singular.php:53 0.6687 18055696 6. locate_template($template_names = [0 => 'partials/single/layout-post.php', 1 => 'partials/single/layout.php'], $load = TRUE, $load_once = FALSE, $args = []) /volume1/web/www/blog/wp-includes/general-template.php:206 0.6688 18055808 7. load_template($_template_file = '/volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/layout.php', $load_once = FALSE, $args = []) /volume1/web/www/blog/wp-includes/template.php:745 0.6688 18056160 8. require('/volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/layout.php') /volume1/web/www/blog/wp-includes/template.php:812 0.6776 18067144 9. get_template_part($slug = 'partials/single/content', $name = ???, $args = ???) /volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/layout.php:54 0.6776 18067496 10. locate_template($template_names = [0 => 'partials/single/content.php'], $load = TRUE, $load_once = FALSE, $args = []) /volume1/web/www/blog/wp-includes/general-template.php:206 0.6776 18067608 11. load_template($_template_file = '/volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/content.php', $load_once = FALSE, $args = []) /volume1/web/www/blog/wp-includes/template.php:745 0.6776 18067912 12. require('/volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/content.php') /volume1/web/www/blog/wp-includes/template.php:812 0.6777 18067912 13. the_content($more_link_text = ???, $strip_teaser = ???) /volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/content.php:19 0.6779 18067944 14. apply_filters($hook_name = 'the_content', $value = '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'...) /volume1/web/www/blog/wp-includes/post-template.php:256 0.6779 18068192 15. WP_Hook->apply_filters($value = '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'..., $args = [0 => '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'...]) /volume1/web/www/blog/wp-includes/plugin.php:205 0.6779 18069568 16. WP_Syntax::beforeFilter($content = '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'...) /volume1/web/www/blog/wp-includes/class-wp-hook.php:324 0.6779 18069568 17. preg_replace_callback($pattern = '/\\s*(.*)<\\/pre>\\s*/siU', $callback = [0 => 'WP_Syntax', 1 => 'substituteToken'], $subject = '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'...) /volume1/web/www/blog/wp-content/plugins/wp-syntax/wp-syntax.php:380 Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /volume1/web/www/blog/wp-content/plugins/wp-syntax/wp-syntax.php on line 380 Call Stack: 0.0000 360448 1. {main}() /volume1/web/www/blog/index.php:0 0.0000 360752 2. require('/volume1/web/www/blog/wp-blog-header.php') /volume1/web/www/blog/index.php:17 0.4648 16540128 3. require_once('/volume1/web/www/blog/wp-includes/template-loader.php') /volume1/web/www/blog/wp-blog-header.php:19 0.4683 16597824 4. include('/volume1/web/www/blog/wp-content/themes/oceanwp/singular.php') /volume1/web/www/blog/wp-includes/template-loader.php:106 0.6687 18055288 5. get_template_part($slug = 'partials/single/layout', $name = 'post', $args = ???) /volume1/web/www/blog/wp-content/themes/oceanwp/singular.php:53 0.6687 18055696 6. locate_template($template_names = [0 => 'partials/single/layout-post.php', 1 => 'partials/single/layout.php'], $load = TRUE, $load_once = FALSE, $args = []) /volume1/web/www/blog/wp-includes/general-template.php:206 0.6688 18055808 7. load_template($_template_file = '/volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/layout.php', $load_once = FALSE, $args = []) /volume1/web/www/blog/wp-includes/template.php:745 0.6688 18056160 8. require('/volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/layout.php') /volume1/web/www/blog/wp-includes/template.php:812 0.6776 18067144 9. get_template_part($slug = 'partials/single/content', $name = ???, $args = ???) /volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/layout.php:54 0.6776 18067496 10. locate_template($template_names = [0 => 'partials/single/content.php'], $load = TRUE, $load_once = FALSE, $args = []) /volume1/web/www/blog/wp-includes/general-template.php:206 0.6776 18067608 11. load_template($_template_file = '/volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/content.php', $load_once = FALSE, $args = []) /volume1/web/www/blog/wp-includes/template.php:745 0.6776 18067912 12. require('/volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/content.php') /volume1/web/www/blog/wp-includes/template.php:812 0.6777 18067912 13. the_content($more_link_text = ???, $strip_teaser = ???) /volume1/web/www/blog/wp-content/themes/oceanwp/partials/single/content.php:19 0.6779 18067944 14. apply_filters($hook_name = 'the_content', $value = '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'...) /volume1/web/www/blog/wp-includes/post-template.php:256 0.6779 18068192 15. WP_Hook->apply_filters($value = '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'..., $args = [0 => '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'...]) /volume1/web/www/blog/wp-includes/plugin.php:205 0.6779 18069568 16. WP_Syntax::beforeFilter($content = '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'...) /volume1/web/www/blog/wp-includes/class-wp-hook.php:324 0.6779 18069568 17. preg_replace_callback($pattern = '/\\s*(.*)<\\/pre>\\s*/siU', $callback = [0 => 'WP_Syntax', 1 => 'substituteToken'], $subject = '2013년 12월 12일 현재 사용중인 워드프레스 Hueman 테마의 경우 반응형 웹(responsive web) 테마다. 그런데 이 테마는 반응형 웹 동작을 위해서, 동영상 등을 임베드할 때 임베드 코드를 div 태그로 감싸는 후크 필터를 쓴다. 그래서 유튜브 동영상 등을 임베드하면 브라우저 창의 크기에 따라 동영상 크기도 자동으로 조절이 된다. 그런데 이 필터가 트위터의 트윗을 임베드할 때도 동작을 해서 이'...) /volume1/web/www/blog/wp-content/plugins/wp-syntax/wp-syntax.php:380

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 '
<div class="video-container">' . $html . '</div>
';
        }
 
}
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 '
<div class="video-container">' . $html . '</div>
 
'; }
        }
 
}
 
/*  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에 쓰이는 함수도 위와 유사한 방식으로 바꿀 수 있을 것이다. 다음에 적용할 일이 있으면 다시 한 번 정리해 보겠다.

뗏목지기

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