如何在自定义分类中添加上传字段?

时间:2014-11-21 作者:Softmixt

我有一个自定义分类法,我想在其中添加一个自定义字段,这似乎很容易,但最困难的部分是当我想添加一个文件输入类型时enctype="multipart/form-data" 我已经将其添加到表单中。

1 个回复
SO网友:Howdy_McGee

Updated 06/06/2016: 使用term_meta 已在WordPress 4.4中实现,但我尚未测试更新的代码,如果有问题,请在下面留下评论。

以下是我将上载字段添加到分类术语中的操作,在本例中,我将其添加到内置的帖子类别中,但您可以修改它以添加到任何分类中。

Step One - 确保我们在表单上使用enctype:

function edit_form_tag( ) {
    echo \' enctype="multipart/form-data"\';
}
add_action( \'category_term_edit_form_tag\' , \'edit_form_tag\' );
add_action( \'{TAXONOMY_HERE}_term_edit_form_tag\' , \'edit_form_tag\' );
你必须更换{TAXONOMY_HERE} 使用实际的分类名称,例如,如果我有一个名为“tax\\u projects”的自定义分类,则操作如下所示:

add_action( \'tax_projects_term_edit_form_tag\' , \'edit_form_tag\' );


Step Two - 将我们的上传字段添加到我们的条款中:

这是相对容易的部分,但由于我们需要输出所有数据,因此很长。我将首先显示上传和输出代码,但不会显示删除代码,因为它是AJAX,所以将在本文末尾添加删除代码。是的heavily commented 所以,只要你觉得合适,随时可以删除评论。

/** Add New Field To Category **/
function additional_category_fields( $term, $tax ) {
    $uploadID   = get_term_meta( $term->term_id, \'_term_image\', true );             // Retrieve our Attachment ID from the post_meta Database Table
    $feedback   = get_term_meta( $term->term_id, \'_term_image_feedback\', true );    // Retrieve any upload feedback from the Optoins Database Table
  ?>

    <tr class="form-field">
        <th scope="row" valign="top"><label for="meta-order"><?php _e( \'Category Image\' ); ?></label></th>
        <td>
            <div id="catImage">

                <!-- Create a nonce to validate against -->
                <input type="hidden" name="upload_meta_nonce" value="<?php echo wp_create_nonce( basename( __FILE__ ) ); ?>" />

                <!-- Define our actual upload field -->
                Please choose an image: <input type="file" name="_uploaded_file" value="" />

                <?php 
                  if( is_numeric( $uploadID ) ) :                                       // IF our upload ID is actually numeric, proceed

                    /***
                    /*  In this case we are pulling an image, if we are uploading
                    /*  something such as a PDF we could use the built-in function
                    /*  wp_get_attachment_url( $id );
                    /*  codex.wordpress.org/Function_Reference/wp_get_attachment_url
                    ***/
                    $imageArr = wp_get_attachment_image_src( $uploadID, \'medium\' );     // Get the URL of the medium sized image
                    $imageURL = $imageArr[0];                                           // wp_get_attachment_image_src() returns an array, index 0 is our URL
                ?>

                    <div id="uploaded_image">
                        <a href="post.php?post=<?php echo $uploadID; ?>&action=edit" target="_blank">Edit Image</a><br />

                        <!-- Display our image using the URL retrieved earlier -->
                        <a href="post.php?post=<?php echo $uploadID; ?>&action=edit" target="_blank"><img src="<?php echo $imageURL; ?>" /></a><br /><br />
                    </div>

                <!-- IF we received feedback, something went wrong and we need to show that feedback. -->               
                <?php elseif( ! empty( $feedback ) ) : ?>

                    <p style="color:red;font-size:12px;font-weight;bold;font-style:italic;"><?php echo $feedback; ?></p>

                <?php endif; ?>

            </div>
            <span class="description"><?php _e( \'Upload an appropriate image.\' ); ?></span>
                <br />
                <br />

            <!-- This link is for our deletion process -->
            <?php if( ! empty( $uploadID ) ) : ?>

                <a href="javascript:void(0)" class="deleteImage" style="color:red;text-decoration:underline;">Delete</a>

            <?php endif; ?>

        </td> 
    </tr>

  <?php
    /** Since we\'ve shown the user the feedback they need to see, we can delete our meta **/
    delete_term_meta( $term->term_id, \'_term_image_feedback\' );
}
add_action( \'category_edit_form_fields\', \'additional_category_fields\', 10, 2 ); 
希望这些评论能够解释任何看似奇怪的事情,但这里我们将简要说明我们正在做的事情,我们将显示上载字段。我们(将)将附件ID保存为术语meta。如果有上传的内容,我们可以检索附件ID并将其显示给用户,这取决于您决定它是图像还是文件,在本例中,它是图像。



Step Three - 上传附件并保存数据

有趣的部分!在这里,我们将进行一些清理,确保用户上载的文件类型正确,否则我们将使用反馈让他们知道。同样,这是一个heavily commented 代码末尾有简要说明。

/** Save Category Meta **/
function save_category_fields( $term_id ) {

    // Make sure that the nonce is set, taxonomy is set, and that our uploaded file is not empty
    if(
      isset( $_POST[\'upload_meta_nonce\'] ) && wp_verify_nonce( $_POST[\'upload_meta_nonce\'], basename( __FILE__ ) ) &&
      isset( $_POST[\'taxonomy\'] ) && isset( $_FILES[\'_uploaded_file\'] ) && !empty( $_FILES[\'_uploaded_file\'] )
    ) {
        $supportedTypes = array( \'image/gif\', \'image/jpeg\', \'image/png\' );                      // Only accept image mime types. - List of mimetypes: http://en.wikipedia.org/wiki/Internet_media_type
        $fileArray      = wp_check_filetype( basename( $_FILES[\'_uploaded_file\'][\'name\'] ) );   // Get the mime type and extension.
        $fileType       = $fileArray[\'type\'];                                                   // Store our file type

        // Verify that the type given is what we\'re expecting
        if( in_array( $fileType, $supportedTypes ) ) {
            $uploadStatus = wp_handle_upload( $_FILES[\'_uploaded_file\'], array( \'test_form\' => false ) );   // Let WordPress handle the upload

            // Make sure that the file was uploaded correctly, without error
            if( isset( $uploadStatus[\'file\'] ) ) {
                require_once(ABSPATH . "wp-admin" . \'/includes/image.php\');

                // Let\'s add the image to our media library so we get access to metadata
                $imageID = wp_insert_attachment( array(
                        \'post_mime_type\'    => $uploadStatus[\'type\'],
                        \'post_title\'        => preg_replace( \'/\\.[^.]+$/\', \'\', basename( $uploadStatus[\'file\'] ) ),
                        \'post_content\'      => \'\',
                        \'post_status\'       => \'publish\'
                    ),
                    $uploadStatus[\'file\']
                );

                // Generate our attachment metadata then update the file.
                $attachmentData = wp_generate_attachment_metadata( $imageID, $uploadStatus[\'file\'] );
                wp_update_attachment_metadata( $imageID,  $attachmentData );


                $existingImage = get_term_meta( $term_id, \'_term_image\', true );        // IF a file already exists in this meta, grab it
                if( ! empty( $existingImage ) && is_numeric( $existingImage ) ) {       // IF the meta does exist, delete it.
                    wp_delete_attachment( $existingImage );
                }

                update_term_meta( $term_id, \'_term_image\', $imageID );                  // Update our meta with the new attachment ID
                delete_term_meta( $term_id, \'_term_image_feedback\' );                   // Just in case there\'s a feedback meta, delete it - theoretically it shouldn\'t exist at this point.
            }
            else {
                $uploadFeedback = \'There was a problem with your uploaded file. Contact Administrator.\';    // Something major went wrong, enable debugging
            }
        }
        else {
            $uploadFeedback = \'Image Files only: JPEG/JPG, GIF, PNG\';   // Wrong file type
        }

        // Update our Feedback meta
        if( isset( $uploadFeedback ) ) {
            update_term_meta( $term_id, \'_term_image_feedback\', $uploadFeedback );
        }
    }
}
add_action ( \'edited_category\', \'save_category_fields\');
因此,上面我们需要确保我们在正确的位置使用正确的数据,我们需要一个分类名称来使用唯一的命名约定,我们还需要确保我们有一个上载的文件。一旦我们知道了这一点,我们就可以使用一些内置函数来获取实际的文件类型,并对照我们需要用户上传的特定类型进行检查。一旦完成了,就可以一帆风顺了——上传文件,生成元数据,并更新我们的术语meta。这个_term_image meta将实际保存一个图像ID,而反馈将保存一个字符串。

你完蛋了。这应该允许用户上载图像(或者您可以修改它以上载文件),您可以通过以下方式获取图像:get_term_meta( $term->term_id, \'_term_image, true );. 我们唯一缺少的是允许用户删除图像



Step Four - 删除上载的图像

通常我不喜欢将JS和PHP混合在一起,但在这种情况下,我找不到解决方法。在上面的顶部additional_category_fields 函数我们需要添加一些Javascript,因为JQuery已经在管理面板中排队,我们可以直接内联它:

<script type="text/javascript">
    jQuery(function($) {

        /** Add our listener to the delete button **/
        $(\'.deleteImage\').click(function(){

            /** Make sure the user didn\'t hit the button by accident and they really mean to delete the image **/
            if( $( \'#uploaded_image\' ).length > 0 && confirm( \'Are you sure you want to delete this file?\' ) ) {
                var result = $.ajax({
                    url: \'/wp-admin/admin-ajax.php\',
                    type: \'GET\',
                    data: {
                        action: \'tax_del_image\',
                        term_id: \'<?php echo $term->term_id; ?>\',
                        taxonomy: \'<?php echo $tax; ?>\'
                    },
                    dataType: \'text\'
                });

                result.success( function( data ) {
                    $(\'#uploaded_image\').remove();
                });
                result.fail( function( jqXHR, textStatus ) {
                    console.log( "Request failed: " + textStatus );
                });
            }
        });
    });
</script>
这里使用ajax传递当前term_id 和当前taxonomy 调用的函数tax_del_image. PHP函数如下所示:

/** Metabox Delete Image **/
function tax_del_image() {

    /** If we don\'t have a term_id, bail out **/
    if( ! isset( $_GET[\'term_id\'] ) ) {
        echo \'Not Set or Empty\';
        exit;
    }

    $term_id = $_GET[\'term_id\'];
    $imageID = get_term_meta( $term_id, \'_term_image\', true );  // Get our attachment ID

    if( is_numeric( $imageID ) ) {                              // Verify that the attachment ID is indeed a number
        wp_delete_attachment( $imageID );                       // Delete our image
        delete_term_meta( $term_id, \'_term_image\' );                // Delete our image meta
        delete_term_meta( $term_id, \'_term_image_feedback\' );   // Delete our feedback in the off-chance it actually exists ( it shouldn\'t )
        exit;
    }

    echo \'Contact Administrator\';   // If we\'ve reached this point, something went wrong - enable debugging
    exit;
}
add_action( \'wp_ajax_tax_del_image\', \'tax_del_image\' );


Step Five - 清理

截至WordPress 4.1,我们有一个pre_delete_term function 它允许我们在删除术语时清理数据库。

/** Delete Associated Media Upon Term Deletion **/
function delete_associated_term_media( $term_id, $tax ){
    global $wp_taxonomies; 

    if( isset( $term_id, $tax, $wp_taxonomies ) && isset( $wp_taxonomies[$tax] ) ) {
        $imageID = get_term_meta( $term_id, \'_term_image\', true );

        if( is_numeric( $imageID ) ) {
            wp_delete_attachment( $imageID );
        }
    }
}
add_action( \'pre_delete_term\', \'delete_associated_term_media\', 10, 2 );
此功能将负责删除,快速简单。把一切结合起来,把它拍成functions.php 文件(或将其转换为插件或外部文件等),您就有了一个术语的上载字段!别生气!



Bonus - 术语更新重定向

因此,就目前而言,每当更新时,术语就会重定向回父级“添加术语”页面-如果您发现这个讨厌的用户birgire有一个解决方案-Modify Term Update Redirection

结束

相关推荐

Custom taxonomy template loop

我知道这个问题问得很多,但我找不到一个适合我的答案。我制作了一些自定义帖子类型和一些自定义分类法。我有自定义的帖子类型Products 并与分类法相联系Product Categories. 当用户在产品页面上单击产品类别时,我想向他显示该特定类别中的所有产品。问题是,产品类别将约为50种。现在我发现的唯一一件事就是把这个<?php $loop = new WP_Query( array( \'post_type\' => \'all_products\', \'posts_per_page\