구글 애드센스 광고는 하나의 사이트에 여러 게시자(애드센스 계정)가 자신의 광고를 게시할 수 있습니다. 커뮤니티 사이트에서 게시글 작성자의 글에 작성자의 광고가 출력되는 것. 워드프레스 사이트에서 포스트 작성자(Author)의 포스트에 작성자의 애드센스 광고가 출력되는 것과 같습니다.
여러 애드센스 게시자의 광고를 하나의 사이트 또는 포스트에 게시할 수 있는 정책이 있고, 여러 사람이 포스팅할 수 있는 시스템이 있으며, 여러 사람이 자신의 광고 코드를 각각 등록할 수 있는 화면을 쉽게 구성할 수 있는 CMS로 워드프레스만 한 것이 없습니다.
그러나, 애드센스의 정책을 준수하여 올바른 광고 게시를 위해서는 시스템보다 게시자(Author)의 꼼꼼함이 우선돼야 합니다. 애드센스 광고 코드는 쉽게 얻을 수 있으며, 코드 삽입이 간단합니다. 그러나 여러 광고 유형이 있고, 게시하려는 사이트의 특성이 있으므로 사이트 운영자가 기준을 설정하여 게시하도록 정해야 합니다. 그렇지 않으면 광고 게재와 관련한 빈번한 오류와 번거로움으로 손해가 더 큰 경우가 생깁니다.
글에서는 광고 게재 기준을 정하여 아주 간단하게 필터를 사용하여 싱글 포스트 페이지의 콘텐츠 위와 아래에 글 작성자의 광고를 출력하는 방법을 알아봅니다. 다음 그림은 글에서 게재하는 광고 위치와 간단한 설명입니다.
위의 그림에 있지만, 글에서는 인피드 광고 중 측면 이미지 유형을 게재합니다. 하나의 광고 코드를 반복해서 사용할 수 있으므로 하나의 입력 필드만 구성하면 되고, 화면 크기에 반응하여 어우러지는 광고이므로 여러모로 편리합니다. 광고 코드 정보 입력 화면을 먼저 구성합니다.
애드센스 광고 코드 등록
구글 애드센스 인피드 광고 중 측면 이미지 유형의 광고 코드는 보통 다음과 같습니다.
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:block"
data-ad-format="fluid"
data-ad-layout="image-side"
data-ad-layout-key="-fd+3i+5b-it+jd"
data-ad-client="ca-pub-12345678911121314"
data-ad-slot="9876543214789"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
쉽게 생각할 수 있는 것으로, 위의 정보 중 data-ad-layout-key
, data-ad-client
, data-ad-slot
속성값을 입력할 수 있는 필드를 각 사용자 프로필 페이지에 만들고, 전체 코드에 해당 데이터를 조건(포스트 작성자 – Author)에 의해 추가한 후 the_content
필터 훅으로 싱글 포스트 콘텐츠 위와 아래에 광고를 출력되도록 하는 것입니다.
다음 코드는 광고 출력을 제외하고, 프로필 페이지에 3가지 정보를 입력하면, 사용자 메타데이터({prefix}_usermeta
테이블)로 저장되도록 구성한 것입니다.
<?php
/**
* 회원(글쓴이)의 구글 광고 게재를 위한 특정 프로필 페이지의 데이터 입력 폼
*/
// 로그인 사용자가 자신의 프로필 페이지를 볼 때
add_action( 'show_user_profile', 'show_extra_profile_fields' );
// 관리자(다른 사용자의 프로필 관리 권한이 있는 사용자)가 특정 사용자의 프로필 페이지를 볼 때
add_action( 'edit_user_profile', 'show_extra_profile_fields' );
function show_extra_profile_fields( $user ) {
$ads_code = get_user_meta( $user->ID, 'ads_code', true );
$ca_pub = isset( $ads_code[ 'ca_pub' ] ) ? $ads_code[ 'ca_pub' ] : '';
$infeed_slot = isset( $ads_code[ 'infeed_slot' ] ) ? $ads_code[ 'infeed_slot' ] : '';
$infeed_key = isset( $ads_code[ 'infeed_key' ] ) ? $ads_code[ 'infeed_key' ] : '';
?>
<h3>구글 애드센스 코드</h3>
<table class="form-table">
<tr>
<th><label for="ca_pub">애드센스 계정 코드</label></th>
<td>
<input id="ca_pub" name="ca_pub" class="regular-text code" value="<?php echo $ca_pub; ?>">
<p class="description"><strong>data-ad-client="ca-pub-1234567891011"</strong> 형식에서 <strong>ca-pub-</strong>를 제외한 <strong>1234567891011</strong> 숫자만 입력하세요.</p>
</td>
</tr>
<tr>
<th><label for="infeed_slot">콘텐츠 영역 인피드 광고 slot 코드</label></th>
<td>
<input id="infeed_slot" name="infeed_slot" class="regular-text code" value="<?php echo $infeed_slot; ?>">
<p class="description">콘텐츠 영역 광고는 <strong>인피드 광고 - 측면 이미지 유형</strong> 광고가 출력됩니다.</p>
<p class="description"><strong>data-ad-slot="123456789"</strong> 형식에서 <strong>123456789</strong> 숫자만 입력하세요.</p>
</td>
</tr>
<tr>
<th><label for="infeed_key">콘텐츠 영역 인피드 광고 layout-key</label></th>
<td>
<input id="infeed_key" name="infeed_key" class="regular-text code" value="<?php echo $infeed_key; ?>">
<p class="description">콘텐츠 영역 광고는 <strong>인피드 광고 - 측면 이미지 유형</strong> 광고가 출력됩니다.</p>
<p class="description"><strong>data-ad-layout-key="-aa+5b+5c-is+jd"</strong> 형식에서 <strong>-aa+5b+5c-is+jd</strong>만 입력하세요.</p>
</td>
</tr>
</table>
<?php
}
위의 코드 예시처럼 핵심 정보만 입력하고, 하나의 필드에 배열 데이터로 저장하며, 입력 데이터 형식을 최대한 제어(Sanitize & Validate)하여 실제 광고가 출력되도록 하는 것이 적절하다고 생각합니다. 회원의 실수를 최대한 줄일 수도 있어 오류를 예방하는 데도 좋습니다. 다음 그림은 위의 코드를 사용할 때 프로필 페이지에 나타나는 화면입니다.
그러나, 이 글에서는 위의 코드를 사용하지 않고 더 간단하게 구성하므로 필요하다면 참고하여 더 좋은 코드로 만드세요.
입력 필드를 사용자 프로필 페이지에 만들지 않아도 됩니다. 다음 글에서 소개한 것처럼 옵션(메뉴) 페이지를 만들고 입력 폼을 구성하여 저장한 데이터를 옵션 데이터가 아닌 사용자의 메타데이터로 저장하도록 구성할 수 있습니다.
사이트 전역 데이터를 위한 워드프레스 커스텀 옵션 페이지 추가
다음 코드는 이 글에서 구성하는 전체 코드로, 혹시 따라 하는 분이나 Child Theme를 테마를 사용하지 않는 분과 템플릿 파일을 편집하지 않는 분을 위해서 간단하게 플러그인으로 처리하였습니다.
<?php
/**
* Plugin Name: 멀티 사용자 애드센스
* Description: 싱글 포스트 페이지에서 글쓴이의 구글 광고 게재. 글쓴이가 코드 정보를 등록하지 않았다면, 관리자 광고 출력
* Author: 방문자와 운영자
*/
/**
* 회원(글쓴이)의 구글 광고 게재를 위한 특정 데이터 입력 폼
*/
// 로그인 사용자가 자신의 프로필 페이지를 볼 때
add_action( 'show_user_profile', 'show_extra_profile_fields' );
// 관리자(다른 사용자의 프로필 관리 권한이 있는 사용자)가 특정 사용자의 프로필 페이지를 볼 때
add_action( 'edit_user_profile', 'show_extra_profile_fields' );
function show_extra_profile_fields( $user ) {
$content_ad = get_user_meta( $user->ID, 'content_ad', true );
?>
<h3>구글 애드센스 코드</h3>
<table class="form-table">
<tr>
<th><label for="content_ad">콘텐츠 영역 인피드 광고 코드</label></th>
<td>
<textarea id="content_ad" name="content_ad" rows="10" cols="80"><?php echo $content_ad; ?></textarea>
<p class="description">콘텐츠 영역 광고는 <strong>인피드 광고 - 측면 이미지 유형</strong> 광고를 사용합니다.</p>
<p class="description">인피드 광고는 코드 반복 사용이 가능하므로 필드에 광고 코드를 등록하면 콘텐츠 위, 아래 영역에 출력됩니다.</p>
<p class="description">같은 코드를 반복 사용하므로 반드시 인피드 광고를 사용하세요. 애드센스 정책에 어긋나지 않도록 주의하세요.</p>
<p class="description">아래 코드는 제외하고 입력하세요.</p>
<p class="description"><?php echo esc_html( '<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' ); ?></p>
</td>
</tr>
</table>
<?php
}
/* 애드센스 데이터 저장, User meta data */
// 로그인 사용자가 자신의 프로필 페이지에 추가된 커스텀 필드 데이터를 업데이트할 때
add_action( 'personal_options_update', 'save_extra_profile_fields' );
// 관리자(다른 사용자의 프로필 관리 권한이 있는 사용자)가 특정 사용자의 프로필 페이지에 추가된 커스텀 필드 데이터를 업데이트할 때
add_action( 'edit_user_profile_update', 'save_extra_profile_fields' );
function save_extra_profile_fields( $user_id ) {
$update_content_ad = trim( esc_textarea( $_POST[ 'content_ad' ] ) );
update_user_meta( absint( $user_id ), 'content_ad', $update_content_ad );
}
/**
* 싱글 페이지 콘텐츠 위, 아래에 광고 출력
*/
add_filter( 'the_content', 'before_after_content_insert_ads' );
function before_after_content_insert_ads( $content ) {
if ( is_singular( array( 'post' ) ) ) {
// 관리자가 1명이라 가정할 때 관리자 ID (2). 실제 관리자 아이디로 변경 필요.
$admin_ad = html_entity_decode( get_user_meta( 2, 'content_ad', true ) );
$author_ad = html_entity_decode( get_user_meta( get_the_author_meta( 'ID' ), 'content_ad', true ) );
if ( $author_ad ) {
$adblock_content = $author_ad . $content . $author_ad;
} else {
$adblock_content = $admin_ad . $content . $admin_ad;
}
return $adblock_content;
} else {
return $content;
}
}
/**
* 실제 사용한다면 별도 분리하여 다른 코드와 함께 정리하여 사용
* 이미 존재한다면 아래 전부 삭제
*/
add_action( 'wp_head', 'site_head_script' );
function site_head_script() {
?>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<?php
}
중복 요청 파일 코드 adsbygoogle.js
제외하고 광고 코드 전체를 입력하여 싱글 포스트 콘텐츠 위와 아래에 광고를 출력하는데, 포스트 타입을 post에 한정하였습니다. 실제 사이트에서는 일반 회원이 포스트를 작성하는 포스트 타입을 지정하면 되고, 2개 이상이면 이어서 입력하면 됩니다.
//
is_singular( array( 'post' ) )
위의 코드는 포스트 작성자가 광고 코드를 입력하지 않으면 관리자의 광고가 출력되도록 관리자 ID(2, 가정)를 그대로 입력하였는데, 위의 코드 또는 옵션 페이지 등에서 포스트 작성자 광고가 없을 때 출력할 관리자 ID 필드를 추가로 만들어 위의 코드에 반영할 수도 있습니다.
// 숫자를 실제 관리자 아이디로 변경
get_user_meta( 2, 'content_ad', true )
싱글 포스트 조건과 함께 필터 훅을 사용한 것이므로 다음 코드만으로 해당 글의 작성자 ID를 얻을 수 있습니다. 가끔 혼동할 경우가 있는데, ‘로그인 회원’이 아니라 ‘포스트 작성자’입니다.
//
get_the_author_meta( 'ID' ) );
PHP 함수 html_entity_decode
사용은 광고 코드의 저장 시 인코드(Encode, Escape)하여 저장하므로 출력 시 디코드(Decode)하여 소스가 그대로 노출되지 않고 실행되도록 한 것입니다. 이와 비슷한 함수로 워드프레스에서 wp_kses_decode_entities
함수가 있지만, 숫자형으로 부호화된 HTML 문자만 디코드하므로 소스가 올바르게 실행되지 않습니다.
코드에 사용한 일부 CSS description
, form-table
클래스는 워드프레스에서 프로필 페이지에 사용하는, 이미 존재하는 클래스로, 소스를 보면 확인할 수 있습니다. 프로필 페이지에 존재하는 클래스를 그대로 사용하는 것이 좋습니다.
프로필 페이지
위의 코드를 보면 다음의 4가지 액션 훅을 볼 수 있습니다.
add_action( 'show_user_profile', 'show_extra_profile_fields' );
add_action( 'edit_user_profile', 'show_extra_profile_fields' );
add_action( 'personal_options_update', 'save_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'save_extra_profile_fields' );
프로필 페이지는 회원별 개인 설정(툴바 등), 이름 설정 섹션, 연락처(Contact) 정보 섹션, 이 글에서 사용하는 확장 정보(메타데이터) 섹션 등으로 구분되어 있습니다.
예를 들어, 연락처 정보에 트위터 계정(url) 입력 필드를 추가하거나 특정 연락처 필드를 제거하기 위해서는 다음 코드처럼 user_contactmethods
필터를 사용할 수 있습니다.
//https://codex.wordpress.org/Plugin_API/Filter_Reference/user_contactmethods#Examples
add_filter( 'user_contactmethods', 'modify_user_contact_methods' );
function modify_user_contact_methods( $user_contact ) {
// Add user contact methods
$user_contact['skype'] = __( 'Skype Username' );
$user_contact['twitter'] = __( 'Twitter Username' );
// Remove user contact methods
unset( $user_contact['aim'] );
unset( $user_contact['jabber'] );
return $user_contact;
}
이 글에서는 프로필 페이지 확장 정보 섹션에 필드를 추가했는데, 이때는 사용한 훅처럼 2가지를 함께 고려합니다.
- 로그인 회원이 자신의 프로필 페이지에 접근하거나 업데이트
- 다른 사용자 정보를 관리할 권한이 있는 로그인 회원(보통 관리자,
edit_users
Capability)이 다른 사용자의 프로필 페이지에 접근하거나 업데이트
결과, 정리
실제 광고 코드로 조건에 따라 올바르게 광고가 게재되는지 확인하기 어려울 수 있으므로 간단하게 일반 문자를 입력하여 결과를 확인합니다.
관리자 프로필 페이지 광고 코드 입력란에는 ‘관리자 광고’라 입력하고 저장. 임시 사용자를 만든 후 로그인하여 프로필 페이지 광고 코드 입력 필드에 ‘작성자 광고’라 입력하고, 임시의 포스트 하나를 작성(Draft 저장)하여 미리 보기 후 포스트 콘텐츠 영역 위와 아래 출력되는 텍스트를 확인하면 됩니다.
관리자와 임시 사용자의 광고 코드 둘 다 있다면, 임시 사용자가 작성한 임시 포스트 콘텐츠 영역 위와 아래에는 ‘작성자 광고’가 표시되어야 하며, 임시 사용자의 광고 코드가 없다면 ‘관리자 광고’가 표시되면 됩니다.
‘필진’이라고도 부르는 글 작성자에게 원고료 대신에 광고 수익을 가져다줄 워드프레스 사이트를 만들어 운영하는 것도 좋습니다. 다만, 광고 코드 등록 가능 그룹(Role)을 별도로 지정하여 신뢰할 수 있는 필진에게만 제공하는 것이 필요할 것입니다.