이미지를 편집할 때 포스트 데이터와 메타 데이터 업데이트

연재고품격 고품질 워드프레스 무료 사진 저장소완결2

앞 장에서 이미지를 등록할 때 이미지 포스트의 캡션(post_excerpt)에 이미지 포스트의 제목 데이터를 삽입하여 포스트 데이터를 업데이트하도록 처리했습니다. 추가한 코드 기준으로 풀어 말하면, 이미지 포스트의 메타 데이터 중 ‘title’ 배열 데이터를 캡션 데이터에 반영하였습니다. 원본 이미지 업로드 과정을 기준으로 말한다면, 원본 이미지의 EXIF ‘title’ 필드의 데이터가 워드프레스 이미지 포스트의 메타 데이터 ‘title’ 필드에 저장되었고, 그 저장된 데이터를 캡션 데이터에 추가한 것입니다.

또, 이미지 포스트에 연결된 분류 ‘phototag’ term 데이터를 이미지 포스트의 ‘대체 텍스트(alt, _wp_attachment_image_alt 필드)’와 ‘설명(post_content)’ 필드에 텍스트 데이터로 저장하였습니다. 이 역시 풀어서 말하면, 원본 이미지에서 가져온 데이터를 워드프레스 이미지 포스트 메타 데이터로 저장한 후 해당 이미지 포스트의 term, 대체 텍스트, 설명 필드 데이터에 저장한 것입니다.

이런 과정은 원본 이미지를 업로드할 때 내부적으로 처리되는 과정으로 이미지 등록자의 의도와 관계가 없습니다. 그리고, 이런 방법은 예제 사이트의 기준에 따라 한꺼번에 대량의 이미지를 업로드하여 등록의 효율을 도모하는 데 필요하다고 이미 말했습니다.

워드프레스 데이터 일관성 유지

대량 등록 또는 개별 등록으로 원본 이미지의 메타 데이터를 워드프레스 기준과 구성 사이트 기준에 맞춰 체계적인 데이터로 자동 등록하는 것은 콘텐츠 등록 효율에 당연히 필요하지만, 워드프레스 데이터로 저장되었을 때 등록자가 수정할 수 있는 범위도 제공해야 합니다. 또, 사이트 운영 기준에 따라 특정 데이터는 편집 제한을 두어 일관성 있는 데이터를 유지해야 할 필요도 있습니다.

다음 그림은 완성 예제에 있는 이미지 포스트 중 하나인 제목 ‘멕시코에서’ 이미지 포스트 편집 화면입니다. 편의를 위해 이미지는 노출하지 않고 캡쳐한 것입니다. 현재 완성되지 않은 예제의 제목 ‘멕시코에서’ 이미지 포스트 편집 화면과 비교하며 보세요.

완성 예제의 미디어 편집 화면

그림에서 ‘X’ 표시의 필드나 메타박스는 등록자가 편집할 수 없는 필드를 뜻합니다. 관리자는 카메라 분류만 예외로 두며, 나머지 3개의 텍스트 필드는 일반 콘텐츠 등록 회원처럼 직접 변경할 수 없습니다.

‘카메라’ 메타박스는 바로 위의 ‘미디어태그’ 분류와 같은 수평 구조의 속성을 가지고 있지만 편집할 수 없습니다. 카메라 정보는 원본 이미지의 데이터를 그대로 가져오며 데이터가 없다면 추가하지 않는다는 사이트 기준에 따라 정한 결과입니다.

‘미디어분류’, ‘2차분류’ 분류 메타박스는 ‘선택 변경’ 이나 ‘추가 선택’은 가능하지만, 분류의 ‘term’을 추가하거나 편집할 수 없습니다. 각자의 구성 사이트 편집 화면과 비교하면 금방 알 수 있습니다. 이것도 ‘고정 분류’로 사이트 관리자(운영자)가 정한다는 사이트 운영 가상 기준에 의한 결과입니다. 따라서 관리자는 예외로 둡니다.

‘미디어태그’ 분류는 원본 이미지의 데이터가 있다면 가져오지만, 등록 후에도 등록자가 추가하거나 제외할 수 있도록 기준을 정하였습니다.

미디어 편집 화면의 포스트 업데이트

그림에 있는 3개의 화살표를 보고 이미 짐작한 분도 있을 터인데, 다음과 같은 뜻입니다.

  • 미디어 편집 화면에서 포스트를 업데이트할 때 ‘제목’ 필드의 데이터를 ‘캡션’ 데이터에 저장
  • 따라서 ‘캡션’ 데이터를 편집한 후 업데이트해도 ‘캡션’ 데이터는 ‘제목’ 데이터를 가지므로 변경 불가
  • 미디어 편집 화면에서 포스트를 업데이트할 때 해당 포스트에 연결(저장)된 ‘미디어태그(phototag)’의 ‘term’ 데이터를 ‘텍스트 유형’의 데이터로 변경하여 ‘대체 텍스트’와 ‘설명’ 필드 데이터로 저장
  • 따라서 ‘대체 텍스트’와 ‘설명’ 필드 데이터는 직접 변경 불가
  • ‘캡션’, ‘대체 텍스트’, ‘설명’ 필드 데이터 제어는 관리자와 이하 회원을 모두 포함
  • 이 데이터 제어는 ‘미디어 편집 화면’에서 포스트를 업데이트할 때 적용

테마 파일에 코드를 추가하여 앞의 데이터 제어 내용을 적용하고 실제 테스트하면 충분히 이해할 수 있습니다. 테마 루트 inc/image-functions.php 파일을 열어 맨 아래에 다음 코드를 추가하고 저장하세요.

add_filter( 'edit_attachment', 'insert_alt_caption_field' );
function insert_alt_caption_field( $post_id ) {
    if ( is_admin() && get_post_type() == 'attachment' ) { // 생략가능
        remove_action( 'edit_attachment', 'insert_alt_caption_field' );
        $title = get_the_title( $post_id );
        $ptags = array();
        $terms = get_the_terms( $post_id , 'phototag' );
        if( $terms ) {
            foreach( $terms as $term ) {
                $ptags[] = $term->name;
            }
            $phototag = implode( ', ', $ptags );
        }
        update_post_meta( $post_id, '_wp_attachment_image_alt', $phototag );
        wp_update_post( array( 'ID' => $post_id, 'post_content' => $phototag, 'post_excerpt' => $title ) ); // 검색을 위해
    } // 생략가능
}

미디어 편집 화면에서 포스트를 업데이트할 때 데이터를 원하는 방향으로 처리하기 위해 1번 줄의 edit_attachment 훅을 사용하였습니다. 미디어 편집 화면은 ‘관리페이지’, ‘attachment 포스트 타입’의 조건을 저절로 가진다고 볼 수 있으므로 3번, 16번 줄은 없어도 됩니다.

5번 줄에서 15번 줄의 코드가 데이터 제어에 관한 것으로, 대체 텍스트는 ‘커스텀 필드’에 저장되는 데이터이므로 14번 줄에서 update_post_meta 함수를 사용하여 저장하고, 설명과 캡션 데이터는 포스트 필드에 저장되는 데이터이므로 wp_update_post 함수를 사용하여 데이터를 저장하는 것입니다.

미디어 편집 화면에서 직접 확인해봅니다. 다음 순서에 따라 진행하세요.

  • 관리페이지에서 제목 ‘멕시코에서’ 이미지 포스트 편집 화면에 접근
  • 제목 필드 데이터를 ‘멕시코에서 – 제목’으로 대체
  • 캡션 필드 데이터를 ‘멕시코에서 – 캡션’으로 대체
  • 대체 텍스트 필드 데이터를 ‘강, 남자, 레포츠, 물보라, 수상스키, 대체텍스트’로 대체
  • 설명 필드 데이터를 ‘강, 남자, 레포츠, 물보라, 수상스키, 설명’으로 대체
  • 업데이트 버튼 클릭 후 결과 확인

‘제목’과  ‘캡션’ 데이터만 ‘멕시코에서 – 제목’으로 변경되고, 나머지는 데이터 변경이 없으면 바른 결과입니다. 다시 다음의 순서에 따라 진행해보세요.

  • 대체 텍스트와 설명 필드의 현재 데이터 기억
  • 미디어태그 메타박스의 term 추가 필드에 ‘멕시코’ 입력 후 ‘추가’ 버튼 클릭
  • 미디어태그 메타박스에서 기존 ‘강’ term 삭제(x)
  • 업데이트 버튼 클릭 후 결과 확인

‘남자, 레포츠, 멕시코, 물보라, 수상스키’의 텍스트와 term이 대체 텍스트 및 설명 필드와 미디어 태그 메타박스의 term에 있다면 올바른 결과입니다.

Infinite loop

앞의 코드 4번 줄에 다음 1번 줄의 코드가 있습니다. 2번 줄처럼 비활성화 또는 삭제한 후 이미지 포스트를 업데이트하면 ‘무한 루프Infinite loop’가 발생합니다. 보통은 ‘메모리 초과’와 같은 메시지를 최종적으로 출력할 것입니다.

remove_action( 'edit_attachment', 'insert_alt_caption_field' );
// remove_action( 'edit_attachment', 'insert_alt_caption_field' );

save_post, edit_attachment 훅은 워드프레스 포스트 저장과 관련한 훅으로 예제처럼 직접 코드 추가를 통해 특정 기능을 정의하며, wp_update_post 함수와 함께 사용할 때 무한 루프가 발생할 수 있으므로 주의하라고 코덱스에서 안내하고 있습니다.

Caution – Infinite loop

save_post 훅을 사용할 때는 ‘리비전’ 포스트와 관련, edit_attachment 훅을 사용할 때는 wp_update_post 함수에 사용한 ‘ID’와 메타 데이터의 값을 전달하는 것과 관련이 있다는 개략적인 이유만 파악하면 됩니다.

무한 루프를 피하고자 예제처럼 remove_action 훅을 추가하는 것으로 쉽게 해결할 수 있으므로 예시나 예제를 통해 직접 경험하는 것이 더 좋습니다.

포스트의 term 데이터

포스트의 term 데이터를 얻기 위해 추가한 코드 중에 다음의 코드가 있습니다. 특정 포스트에 연결된 특정 분류의 term 오브젝트(이후부터 ‘데이터’라 표기)를 구하는 함수로, 코드에서는 분류 ‘phototag’의 term 중 포스트에 연결된 term 데이터를 말합니다.

// 분류 phototag term
$terms = get_the_terms( $post_id , 'phototag' );

위의 코드가 어떤 데이터를 가지는지 확인하기 위해 편집기로 연습장 파일을 열어 다음 코드의 2번과 3번 줄만 추가하고 저장합니다. 1번 줄과 4번 줄은 추가 위치를 전달하기 위한 것이므로 추가하지 마세요.

echo '긴 축: ' . get_post_meta($attach_id, 'pic_axis', true) . '<br>'; // 이 줄 아래
$terms = get_the_terms( $attach_id , 'phototag' );
echo '<pre>' . print_r( $terms, true ) . '</pre>';
echo '</td>'; // 이 줄 위

사이트에서 연습장 페이지를 새로 고쳐 맨 아래의 결과를 확인하면, 포스트 제목 ‘멕시코에서 – 제목’ 이미지의 경우 다음의 데이터를 볼 수 있습니다. ‘term_id’, ‘term_taxonomy_id’ 키의 데이터는 필자와 다를 수 있습니다.

Array
(
    [0] => WP_Term Object
        (
            [term_id] => 84
            [name] => 남자
            [slug] => %eb%82%a8%ec%9e%90
            [term_group] => 0
            [term_taxonomy_id] => 84
            [taxonomy] => phototag
            [description] => 
            [parent] => 0
            [count] => 1
            [filter] => raw
        )

    [1] => WP_Term Object
        (
            [term_id] => 85
            [name] => 레포츠
            [slug] => %eb%a0%88%ed%8f%ac%ec%b8%a0
            [term_group] => 0
            [term_taxonomy_id] => 85
            [taxonomy] => phototag
            [description] => 
            [parent] => 0
            [count] => 1
            [filter] => raw
        )

    [2] => WP_Term Object
        (
            [term_id] => 88
            [name] => 멕시코
            [slug] => %eb%a9%95%ec%8b%9c%ec%bd%94
            [term_group] => 0
            [term_taxonomy_id] => 88
            [taxonomy] => phototag
            [description] => 
            [parent] => 0
            [count] => 1
            [filter] => raw
        )

    [3] => WP_Term Object
        (
            [term_id] => 86
            [name] => 물보라
            [slug] => %eb%ac%bc%eb%b3%b4%eb%9d%bc
            [term_group] => 0
            [term_taxonomy_id] => 86
            [taxonomy] => phototag
            [description] => 
            [parent] => 0
            [count] => 1
            [filter] => raw
        )

    [4] => WP_Term Object
        (
            [term_id] => 87
            [name] => 수상스키
            [slug] => %ec%88%98%ec%83%81%ec%8a%a4%ed%82%a4
            [term_group] => 0
            [term_taxonomy_id] => 87
            [taxonomy] => phototag
            [description] => 
            [parent] => 0
            [count] => 1
            [filter] => raw
        )

)

위의 결과 데이터를 확인한 후 앞에서 추가한 다음의 코드를 다시 한번 본다면 이해를 더하는 데 도움이 됩니다.

$ptags = array();
$terms = get_the_terms( $post_id , 'phototag' );
if( $terms ) {
    foreach( $terms as $term ) {
        $ptags[] = $term->name;
    }
    $phototag = implode( ', ', $ptags );
}

위의 5번 줄 코드에서 term ‘name’만 가져와 존재하는 term 모두 쉼표로 구분한 텍스트 테이터로 7번 줄에서 변환한 것입니다. 이 변환한 데이터를 이미지 포스트의 일부 필드 데이터로 저장한 것이 앞의 과정이었습니다.

지금 본 것은 ‘특정 포스트의 term’에 관한 것인데, 나중에는 term 자체에 관련한 데이터를 활용하는 과정도 있어, 입문자는 조금 혼동할 수 있습니다. 따라서 조금 전에 살펴본 것처럼 특정 함수나 코드가 어떤 데이터를 불러오는지 먼저 확인하는 단계를 거치면서 실 예제를 경험하면 도움이 되는 때가 많습니다.

다음 링크로 이번 장에서 변경한 파일을 전달합니다. 파일을 받은 후 압축을 풀어 테마 루트에 덮어쓰세요.

정리

다음 장에서는 이미지 등록 권한이 있는 사용자 2명을 추가하고, 각 사용자 계정으로 예제를 위한 이미지 391장을 일괄 업로드합니다. 완성 예제의 올바른 결과와 구성 과정의 도움을 위해 다음의 안내에 따라 진행하세요.

이미지 메타 데이터 배열 구조 복사

다음 데이터는 현재 과정에 존재하는 제목 ‘하바나에서’ 이미지 포스트의 이미지 메타 데이터 및 별도 추가한 커스텀 필드 데이터입니다. 특정 포스트라는 것은 의미가 없고 데이터 구조가 핵심입니다. 이 데이터의 배열 구조는 이후에 나오는 대부분 과정에서 사용하는데, 처음 경험하는 경우에 직관적으로 떠오르지 않아 불편한 때가 있습니다. 다음 데이터를 전부 그대로 복사하여 ‘MS 워드’ 또는 ‘메모장’ 등 별도의 PC 애플리케이션에 붙여넣어 구성 과정에서 해당 내용이 필요할 때 열람하여 도움을 더하거나, 종이에 인쇄하여 책상에 두고 참고하기 바랍니다. 인쇄하는 것이 가장 편리할 것입니다. 다만, 이 부분은 권장 사항이므로 예제 구성과 관련이 없는 선택의 문제입니다.

// _wp_attachment_metadata 필드의 데이터
Array
(
    [width] => 4608
    [height] => 3072
    [file] => havana-2256329.jpg
    [sizes] => Array
        (
            [thumbnail] => Array
                (
                    [file] => havana-2256329-150x150.jpg
                    [width] => 150
                    [height] => 150
                    [mime-type] => image/jpeg
                )

            [medium] => Array
                (
                    [file] => havana-2256329-600x400.jpg
                    [width] => 600
                    [height] => 400
                    [mime-type] => image/jpeg
                )

            [medium_large] => Array
                (
                    [file] => havana-2256329-965x643.jpg
                    [width] => 965
                    [height] => 643
                    [mime-type] => image/jpeg
                )

            [large] => Array
                (
                    [file] => havana-2256329-1280x853.jpg
                    [width] => 1280
                    [height] => 853
                    [mime-type] => image/jpeg
                )

            [large_second] => Array
                (
                    [file] => havana-2256329-1920x1280.jpg
                    [width] => 1920
                    [height] => 1280
                    [mime-type] => image/jpeg
                )

        )

    [image_meta] => Array
        (
            [aperture] => 5.6
            [credit] => 
            [camera] => NIKON D3100
            [caption] => 사진,음악
            [created_timestamp] => 1491824649
            [copyright] => 
            [focal_length] => 35
            [iso] => 220
            [shutter_speed] => 0.008
            [title] => 하바나에서
            [orientation] => 1
            [keywords] => Array
                (
                    [0] => 거리
                    [1] => 구경
                    [2] => 기타
                    [3] => 밴드
                    [4] => 연주
                    [5] => 올드보이
                    [6] => 통기타
                    [7] => 팀
                    [8] => 팁
                    [9] => 합주
                )

            [latitude] => 33.394759220108
            [latitude_ref] => N
            [longitude] => 95.888671879997
            [longitude_ref] => W
        )

)

// _location 커스텀 필드의 데이터
Array
(
    [lat] => 33.394759220108
    [lng] => -95.888671879997
    [post_url] => http://localhost/%ed%95%98%eb%b0%94%eb%82%98%ec%97%90%ec%84%9c
    [img_url] => http://localhost/wp-content/uploads/havana-2256329-150x150.jpg
)

존재하는 이미지 및 term 전체 삭제

지금까지 예제 과정을 모두 따라 했다면 알고 있겠지만, 예제 사이트에 원본 이미지를 업로드하면 이미지 포스트의 제목, 특정 분류에 term, GPS 데이터 등 예제 구성에 필요한 모든 데이터가 자동으로 구성되어 저장됩니다. 올바른 예제 결과를 위해 지금 존재하는 이미지와 term 데이터를 완전히 삭제해야 합니다. 다음 순서에 따르세요.

  • 관리페이지 미디어 라이브러리 목록에서 존재하는 모든 이미지를 삭제합니다.
  • 관리페이지 미디어 메뉴 하위 ‘미디어분류’, ‘2차분류’, ‘미디어태그’, ‘카메라’ 메뉴를 각각 클릭한 후 존재하는 모든 term을 삭제합니다.
  • ‘미디어태그’의 경우 한 페이지 이상일 수 있으므로 확인하여 모두 삭제합니다.

연습장 파일

나중에 다시 추가할 연습 코드를 위해 다음 코드 전체를 복사하여 연습장 파일의 코드와 완전히 대체하고 저장하여 초기화합니다.

<?php
/**
 * Template Name: _연습장
 */

get_header(); ?>

    <div id="primary" class="content-area">
        <main id="main" class="site-main">

        <?php
        // 여기서



        // 여기 사이에
        ?>

        </main><!-- #main -->
    </div><!-- #primary -->

<?php
get_footer();

예제 목차

0. 고품격 고품질 워드프레스 무료 사진 저장소

1. 예제 구성 환경과 파일

2. XAMPP, 워드프레스, 테마, 플러그인 설치와 설정

3. 테마 Pics Press

4. page 포스트 타입과 페이지 템플릿, 메뉴 구성

5. 워드프레스 핵심 용어 짚기

6. 워드프레스 포스트 타입 attachment

7. 워드프레스 이미지 사이즈

8. 워드프레스 이미지 사이즈 추가 및 변경

9. 워드프레스 이미지 파일 제어

10. 타입 attachment 템플릿과 image.php

11. 워드프레스 이미지 메타 데이터

12. GPS 데이터를 워드프레스 메타 데이터로 저장

13. 이미지 메타 데이터를 포스트 메타 데이터에 추가

14. Attachment 타입을 위한 워드프레스 커스텀 분류 등록

15. 이미지 메타 데이터를 워드프레스 분류와 필드 데이터에 저장

» 이미지를 편집할 때 포스트 데이터와 메타 데이터 업데이트

17. 워드프레스 미디어 파일 업로드

18. 워드프레스 싱글 이미지 포스트 페이지

19. 워드프레스 아바타와 Author Archives

20. 워드프레스 이미지 사이즈별 데이터 출력

21. 워드프레스 폼 요소로 원하는 이미지 사이즈 다운로드

22. 워드프레스 텍스트 단락 및 줄 바꿈, wpautop

23. 워드프레스 사진의 EXIF 데이터 출력

24. 구글 지도에 표시하는 사진 촬영 위치

25. 워드프레스 attachment 포스트 타입의 아카이브

26. 워드프레스 함수로 자바스크립트 변수 데이터 생성

27. 워드프레스 커스텀 검색 – 쿼리 변수

28. 워드프레스 커스텀 검색 – 검색 폼과 쿼리 데이터

29. 워드프레스 커스텀 포스트 타입 ‘pic_album’

30. 커스텀 포스트 타입의 싱글 페이지

31. 워드프레스 WP_Query

32. 커스텀 쿼리, 페이지 템플릿, 포스트 아카이브

33. 분류 기준의 관련 포스트 커스텀 쿼리

34. wpdb 클래스로 구글 지도에 마커와 섬네일 표시

35. 워드프레스 분류 데이터 쿼리 클래스, WP_Term_Query

36. 워드프레스 템플릿 태그

37. 워드프레스 옵션 페이지, 옵션 필드

38. 워드프레스 사이트 프런트 페이지

39. 사이트 메뉴 및 포스트 페이지 링크

40. 워드프레스 Transient API

41. 워드프레스 분류의 term 데이터를 캐시 데이터로 생성

42. 워드프레스 역할 그룹과 권한으로 구성 요소 제어

43. 간단한 워드프레스 코멘트 폼 수정

44. 워드프레스 대시보드 위젯 추가

45. 워드프레스 REST API 간략 이해

46. 워드프레스 REST API 응답에 커스텀 필드 추가

47. 워드프레스 REST API 커스텀 라우트 및 엔드포인트

48. 워드프레스 REST API 커스텀 엔드포인트로 구글 클러스터 지도 마커와 인포 윈도 표시

49. 워드프레스 REST API, Underscore.js 자바스크립트 템플릿, 포스트 Ajax Load More

50. 워드프레스 REST API, Underscore.js 자바스크립트 템플릿, 코멘트 Ajax Load More

51. 워드프레스 REST API 인증과 제한 및 제어