我编写了一个插件,其中在右下角有一个小聊天图标,但是我希望用户能够从Media Library中选择一个图像作为图标。如何使用Wordpress API做到这一点?图像是插件中的设置(只能由管理员更改)

评论

您应该包括wp.media以允许自定义上载,并为此选择媒体文件。 WPSE有很多示例,但是也许这篇文章对您有所帮助jeroensormani.com/…您还可以在github上找到示例,尤其是来自ocean90-github.com/ocean90/media-modal-demo

#1 楼

您应该使用wp.media来使用WordPress媒体管理器对话框。

首先,需要排队脚本:

// As you are dealing with plugin settings,
// I assume you are in admin side
add_action( 'admin_enqueue_scripts', 'load_wp_media_files' );
function load_wp_media_files( $page ) {
  // change to the $page where you want to enqueue the script
  if( $page == 'options-general.php' ) {
    // Enqueue WordPress media scripts
    wp_enqueue_media();
    // Enqueue custom script that will interact with wp.media
    wp_enqueue_script( 'myprefix_script', plugins_url( '/js/myscript.js' , __FILE__ ), array('jquery'), '0.1' );
  }
}


您的HTML可能是像这样(请注意,我的代码在插件设置中使用附件ID代替了您回答中的图像URL,我认为它会更好。例如,使用ID可以在需要时获得不同的图像大小):

$image_id = get_option( 'myprefix_image_id' );
if( intval( $image_id ) > 0 ) {
    // Change with the image size you want to use
    $image = wp_get_attachment_image( $image_id, 'medium', false, array( 'id' => 'myprefix-preview-image' ) );
} else {
    // Some default image
    $image = '<img id="myprefix-preview-image" src="https://some.default.image.jpg" />';
}

  echo $image; ?>
 <input type="hidden" name="myprefix_image_id" id="myprefix_image_id" value="<?php echo esc_attr( $image_id ); ?>" class="regular-text" />
 <input type='button' class="button-primary" value="<?php esc_attr_e( 'Select a image', 'mytextdomain' ); ?>" id="myprefix_media_manager"/>


myscript.js

jQuery(document).ready( function($) {

      jQuery('input#myprefix_media_manager').click(function(e) {

             e.preventDefault();
             var image_frame;
             if(image_frame){
                 image_frame.open();
             }
             // Define image_frame as wp.media object
             image_frame = wp.media({
                           title: 'Select Media',
                           multiple : false,
                           library : {
                                type : 'image',
                            }
                       });

                       image_frame.on('close',function() {
                          // On close, get selections and save to the hidden input
                          // plus other AJAX stuff to refresh the image preview
                          var selection =  image_frame.state().get('selection');
                          var gallery_ids = new Array();
                          var my_index = 0;
                          selection.each(function(attachment) {
                             gallery_ids[my_index] = attachment['id'];
                             my_index++;
                          });
                          var ids = gallery_ids.join(",");
                          jQuery('input#myprefix_image_id').val(ids);
                          Refresh_Image(ids);
                       });

                      image_frame.on('open',function() {
                        // On open, get the id from the hidden input
                        // and select the appropiate images in the media manager
                        var selection =  image_frame.state().get('selection');
                        var ids = jQuery('input#myprefix_image_id').val().split(',');
                        ids.forEach(function(id) {
                          var attachment = wp.media.attachment(id);
                          attachment.fetch();
                          selection.add( attachment ? [ attachment ] : [] );
                        });

                      });

                    image_frame.open();
     });

});

// Ajax request to refresh the image preview
function Refresh_Image(the_id){
        var data = {
            action: 'myprefix_get_image',
            id: the_id
        };

        jQuery.get(ajaxurl, data, function(response) {

            if(response.success === true) {
                jQuery('#myprefix-preview-image').replaceWith( response.data.image );
            }
        });
}


以及Ajax操作可刷新图像预览:

// Ajax action to refresh the user image
add_action( 'wp_ajax_myprefix_get_image', 'myprefix_get_image'   );
function myprefix_get_image() {
    if(isset($_GET['id']) ){
        $image = wp_get_attachment_image( filter_input( INPUT_GET, 'id', FILTER_VALIDATE_INT ), 'medium', false, array( 'id' => 'myprefix-preview-image' ) );
        $data = array(
            'image'    => $image,
        );
        wp_send_json_success( $data );
    } else {
        wp_send_json_error();
    }
}


PD:这是根据其他答案在此处编写的快速示例。未测试,因为您没有提供有关将使用代码的确切上下文或存在的确切问题的足够信息。

评论


不需要get_image ajax调用。 selection.models [0] .attributes.url在image_frame close上保存选定的图像url。如果要使用特定大小,则需要ajax调用。

–比约恩
20-4-17在17:48



#2 楼

请使用Tareq Hasan,Url的wordpress-settings-api-class:https://github.com/tareq1988/wordpress-settings-api-class


在插件中包含主类class.settings-api.php 。 (此文件https://github.com/tareq1988/wordpress-settings-api-class/blob/master/src/class.settings-api.php)
定义您的选项。要添加媒体上传器,需要使用'type' => 'file'。 (请参阅此示例以更好地理解https://github.com/tareq1988/wordpress-settings-api-class/blob/master/example/procedural-example.php)


评论


我认为没有其他库的解决方案会更好,更可靠;就像wp.media控件一样。

– Bueltge
16年8月17日在12:27

#3 楼

您可以在此网址上找到带有插件的完整代码:http://blog.adlivetech.com/use-wordpress-media-upload-custom-code/

易于使用,只需复制粘贴代码放在您需要的位置

评论


你救了我的命 ! :) 谢谢

– Freestyle09
20年6月23日在7:20

链接烂了

–劳伦斯·谢罗(Lawrence Cherone)
3小时前

#4 楼

由于希望每个用户的图标都不同,因此必须将图像存储在用户配置文件中。这意味着您需要添加一个额外的用户字段:

// create the field
add_action( 'show_user_profile', 'wpse_235406_chaticon' );
add_action( 'edit_user_profile', 'wpse_235406_chaticon' );

function wpse_235406_chaticon ($user) { 
    echo '
    <h3>Chat Icon</h3>
    <table class="form-table">
        <tr>
            <th><label for="chaticon">Chat Icon</label></th>
            <td>
                <input type="file" name="chaticon" id="chaticon" value="' . esc_attr (get_the_author_meta ('chaticon', $user->ID)) . '" class="file-upload" /><br />
                <span class="description">Please select your chat icon.</span>
            </td>
        </tr>
    </table>';
}

// save the field
add_action( 'personal_options_update', 'wpse_235406_chaticon_save' );
add_action( 'edit_user_profile_update', 'wpse_235406_chaticon_save' );

function wpse_235406_chaticon_save ($user_id) {
    if (current_user_can ('edit_user', $user_id)) 
        update_usermeta ($user_id, 'chaticon', $_POST['chaticon']);
}


现在,这使您可以从用户的计算机上载文件。如果希望用户从现有图像中选择文件,则事情会变得更加复杂,因为这时您需要调用媒体库而不是默认的文件上载。史蒂文·斯拉克(Steven Slack)撰写了一篇出色的文章,介绍了如何做到这一点,我不想在这里将其代码粘贴粘贴。

在模板中,您必须区分三种可能性:用户未登录进入,用户登录但没有图标,用户登录并有图标。大致包括以下内容:

$current_user = wp_get_current_user();
if ( 0 == $current_user->ID ) {
  ... do what you want to do for not logged in users ...
  }
else {
  $icon = get_user_meta ($current_user->ID, 'chaticon');
  if (empty($icon)) {
    ... default icon with link to upload possibility ...
    }
  else {
     ... display $icon ...
     }


评论


不,我希望它是一个插件设置

–托马斯
16年8月15日在11:20

您的意思是只有网站管理员才能更改图标,并且每个访问者/用户都一样吗?

– cjbj
16年8月15日在11:24

那将是微不足道的。这是为此的教程:mikejolley.com/2012/12/21/…

– cjbj
16年8月15日在11:28

是的,它自定义按钮的外观(图像)

–托马斯
16年8月15日在11:28

我尝试了本教程,但是对我来说不起作用(已过时?),因为框架不是js对象的一部分

–托马斯
16年8月16日在7:08

#5 楼

我使用了此解决方案(不使用媒体库本身):

在设置隐藏输入值的模式中使用image-picker-lib,该值被发布到选项中。通过获取所有媒体并将其作为选项进行回显,我可以让用户选择一个img。

HTML

<input id="image" name="image" class="validate" type="image" src="<?php echo esc_attr(get_option('image_url')); ?>" id="image_url" width="48" height="48" />
<br>
<a href="#imageModal" class="waves-effect waves-light btn modal-trigger">
    change
</a>
<input id="image_url" name="image_url" type="text" value="" hidden />


PHP / HTML

<div id="imageModal" class="modal">
    <div class="modal-content">
        <select class="image-picker show-html">
            <option data-img-src="<?php echo CM_PATH . "/img/chat_general.png" ?>"  value="0"></option>
            <?php
            $query_images_args = array(
                'post_type'   => 'attachment',
                'post_mime_type' => 'image',
                'post_status' => 'inherit',
                'posts_per_page' => - 1,
            );

            $query_images = new WP_Query( $query_images_args );
            $i = 1;
            foreach ( $query_images->posts as $image ) {
                ?>
                <option data-img-src="<?php echo wp_get_attachment_url($image->ID); ?>"  value="<?php echo $i; ?>"></option>
                <?php
                $i  ;
            }
            ?>
        </select>
    </div>
    <div class="modal-footer">
        <a class="waves-effect waves-light btn change">Choose</a>
    </div>
</div>
</div>
</div>


JS

 $(".change").on("click", function() {
 +            var url = $(".image-picker > option:selected").attr("data-img-src");
 +            $("#image").attr("src", url);
 +            $("#image_url").attr("value", url);
 +            $("#imageModal").closeModal();
 +        });


评论


我认为没有其他库的解决方案会更好,更可靠;就像wp.media控件一样。

– Bueltge
16年8月17日在12:26

@bueltge我同意,但是没有人给出一个直接的答案,我需要时间。因此,如果有人给出了很好的答案,他们就会得到赏金!

–托马斯
16年8月17日在12:40

我认为您的回答也可以作为解决方案,但不是最佳方法。现在,它是问题作者的一部分;您;)来做决定。

– Bueltge
16年8月17日在12:42



随着图像数量的增加,该解决方案很快就会成为问题。 “没有人给出直接的答案”不是借口;您的问题很差,因此您得到的答案很差。您不会向我们展示您尝试过的任何努力,研究或代码,只是“我想这样做,提供现成的解决方案”,这与“为我完成工作”相同。按照bueltge的建议搜索wp.media; WPSE中有数百个示例。如果您在使用时遇到问题,请发布有关此问题的新问题。

– cybmeta
16年8月18日在10:19

我尝试过@cybmeta,这是我最好的尝试,所以不要对此事生硬。如果您不喜欢它,请提出一个更好的解决方案。

–托马斯
16年8月18日在10:27

#6 楼

因此,此答案非常有效。但是为了使其可重用,我将代码转换为函数。因此,要使用此功能,您必须先将其签出以检出脚本。然后像这样声明enqueue

(function($) {
    $(document).ready(function() {
        const wpOpenGallery = function(o, callback) {
            const options = (typeof o === 'object') ? o : {};

            // Predefined settings
            const defaultOptions = {
                title: 'Select Media',
                fileType: 'image',
                multiple: false,
                currentValue: '',
            };

            const opt = { ...defaultOptions, ...options };

            let image_frame;

            if(image_frame){
                image_frame.open();
            }

            // Define image_frame as wp.media object
            image_frame = wp.media({
                title: opt.title,
                multiple : opt.multiple,
                library : {
                    type : opt.fileType,
                }
            });

            image_frame.on('open',function() {
                // On open, get the id from the hidden input
                // and select the appropiate images in the media manager
                const selection =  image_frame.state().get('selection');
                const ids = opt.currentValue.split(',');

                ids.forEach(function(id) {
                    const attachment = wp.media.attachment(id);
                    attachment.fetch();
                    selection.add( attachment ? [ attachment ] : [] );
                });
            });

            image_frame.on('close',function() {
                // On close, get selections and save to the hidden input
                // plus other AJAX stuff to refresh the image preview
                const selection =  image_frame.state().get('selection');
                const files = [];

                selection.each(function(attachment) {
                    files.push({
                        id: attachment.attributes.id,
                        filename: attachment.attributes.filename,
                        url: attachment.attributes.url,
                        type: attachment.attributes.type,
                        subtype: attachment.attributes.subtype,
                        sizes: attachment.attributes.sizes,
                    });
                });

                callback(files);
            });

            image_frame.open();
        }
    })
}(jQuery));


并这样称呼:

wpOpenGallery(null, function(data) {
    console.log(data);
});