最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

custom post types - Force documents to appear in Featured Image dialogue

programmeradmin1浏览0评论

Having a perplexing issue... ...for a custom post-type called 'Resources' I used the 'Featured Image' or 'thumbnail' function within WordPress to allow users to attach documents to 'Resources'. The process itself works exactly as expected and anticipated.

However, setting the site up, someone made a mistake and uploaded two documents and assigned them to the wrong 'Resources'. So Resource A -> Document B and Resource B -> Document A.

When attempting to switch them and clicking 'Edit Featured Image' you are unable to see any of the documents. They clicked 'Remove Featured Image' and then 'Set Featured Image' and when the dialogue opens, still no documents.

In the Wordpress Media Library all of the uploaded and attached documents are there. Visible, with previews, etc. As expected. Here's the first two rows of the Media Library. You can see tons of PDFs that have been successfully uploaded.

The only place where this issue appears is that in the actual 'Featured Image' media dialogue box, WordPress will not display any PDFs.

Here's the CPT supports segment:

$rsc_supports = array(
     'title',
     'editor',
     'thumbnail',
     'page-attributes'
);

Like I said, everything works perfectly - even uploading and attaching PDFs as 'thumbnails' to be associated as attachments with the CPT. When a PDF is attached and you 'Click to edit' the dialogue opens up and you can see the attached PDF in the list. The only failing is that the 'Featured Image' modal/pop-up/dialogue box that loads, is designed to filter out everything except images. This is what that dialogue box looks like on a 'Resource' with nothing attached.

However, if you view another Resource that does have a PDF already attached, you get this:

I have tried the filtering and date dropdown and they don't address this.

I believe this is by design. So my question is, "How do I modify that dialogue box to display all files rather than just images?"

Having a perplexing issue... ...for a custom post-type called 'Resources' I used the 'Featured Image' or 'thumbnail' function within WordPress to allow users to attach documents to 'Resources'. The process itself works exactly as expected and anticipated.

However, setting the site up, someone made a mistake and uploaded two documents and assigned them to the wrong 'Resources'. So Resource A -> Document B and Resource B -> Document A.

When attempting to switch them and clicking 'Edit Featured Image' you are unable to see any of the documents. They clicked 'Remove Featured Image' and then 'Set Featured Image' and when the dialogue opens, still no documents.

In the Wordpress Media Library all of the uploaded and attached documents are there. Visible, with previews, etc. As expected. Here's the first two rows of the Media Library. You can see tons of PDFs that have been successfully uploaded.

The only place where this issue appears is that in the actual 'Featured Image' media dialogue box, WordPress will not display any PDFs.

Here's the CPT supports segment:

$rsc_supports = array(
     'title',
     'editor',
     'thumbnail',
     'page-attributes'
);

Like I said, everything works perfectly - even uploading and attaching PDFs as 'thumbnails' to be associated as attachments with the CPT. When a PDF is attached and you 'Click to edit' the dialogue opens up and you can see the attached PDF in the list. The only failing is that the 'Featured Image' modal/pop-up/dialogue box that loads, is designed to filter out everything except images. This is what that dialogue box looks like on a 'Resource' with nothing attached.

However, if you view another Resource that does have a PDF already attached, you get this:

I have tried the filtering and date dropdown and they don't address this.

I believe this is by design. So my question is, "How do I modify that dialogue box to display all files rather than just images?"

Share Improve this question asked Jun 3, 2020 at 14:45 Tony DjukicTony Djukic 2,2774 gold badges18 silver badges34 bronze badges 6
  • 1 How were they originally set as featured images on the site? It's Core behavior to only allow images as featured, so I'm surprised they were set, unless it was done programmatically. – WebElaine Commented Jun 3, 2020 at 17:33
  • It just allowed it. Nothing was done any different than adding a standard image. That's why this caught me off guard because when I initially built it and set it all up, it allowed the addition of .pdf/.doc files. Had it not allowed it I would have built something different - but now that we've had people add dozens of attachments, I don't want to go back, build it different and then have them re-do all that work. :-( – Tony Djukic Commented Jun 3, 2020 at 17:57
  • Worst case, you could manually assign them in the database. They're just postmeta that includes the attachment ID. – WebElaine Commented Jun 3, 2020 at 20:25
  • That won’t be suitable for the client from a usability/UX experience. – Tony Djukic Commented Jun 3, 2020 at 21:10
  • Since Core doesn't currently support it, you could build an options page where they select the post from a dropdown and assign the image there. Would take some custom coding, but that would give them a user-friendly UI to do it. – WebElaine Commented Jun 4, 2020 at 13:36
 |  Show 1 more comment

2 Answers 2

Reset to default 1 +50

So this may be hacky..

I mean, compared to overriding the default Featured Image panel/component in the Gutenberg block editor, which is not exactly hard, but this one is much simpler and basically just needs a few lines of custom coding. (read till the end to see what I mean)

And I've also tried & tested it working (with both the old/classic editor and the Gutenberg block editor) on WordPress 5.4.2 (the latest release as of writing) as well as WordPress 5.4.1.

So for what you're trying to do, you can override wp.media.model.Query.prototype.sync() (defined in wp-includes/js/media-models.js) which is the function used by the default Featured Image modal for querying attachments via AJAX (admin-ajax.php?action=query-attachments).

Full (JS) Code

wp.media.model.Query.prototype.sync = function( method, model, options ) {
    var args, fallback;

    // Overload the read method so Attachment.fetch() functions correctly.
    if ( 'read' === method ) {
        options = options || {};
        options.context = this;
        options.data = _.extend( options.data || {}, {
            action:  'query-attachments',
            post_id: wp.media.model.settings.post.id
        });

        // Clone the args so manipulation is non-destructive.
        args = _.clone( this.args );

        // Determine which page to query.
        if ( -1 !== args.posts_per_page ) {
            args.paged = Math.round( this.length / args.posts_per_page ) + 1;
        }

        if ( wp.media.frame && 'featured-image' === wp.media.frame.options.state ) {
            // Here I'm allowing image and PDF files only.
            args.post_mime_type = 'image, application/pdf';
        }

        options.data.query = args;
        return wp.media.ajax( options );

    // Otherwise, fall back to `Backbone.sync()`.
    } else {
        /**
         * Call wp.media.model.Attachments.sync or Backbone.sync
         */
        fallback = Attachments.prototype.sync ? Attachments.prototype : Backbone;
        return fallback.sync.apply( this, arguments );
    }
};

But the only thing I added there is this conditional block:

if ( wp.media.frame && 'featured-image' === wp.media.frame.options.state ) {
    // Here I'm allowing image and PDF files only.
    args.post_mime_type = 'image, application/pdf';
}

Which checks if the currently opened modal is the featured image modal and if so, then we modify the post_mime_type argument which defines the MIME type(s) of the attachments being queried.

And that's how you can use this approach to force the Featured Image modal to include files other than images.

Sample PHP Code

Update Jun 13th (to other readers): Just to clarify why should we check for the media-models script, which is because we're overriding something in that script, so if the script is not being loaded on the current page, then there's no need to echo/enqueue our custom script. :)

The following is the PHP code I used to echo the script in the footer on the post editing screen for the default post and page post types:

add_action( 'admin_print_footer_scripts', function () {
    $screen_ids = [ 'post', 'page' ];
    if ( in_array( get_current_screen()->id, $screen_ids ) &&
        wp_script_is( 'media-models' ) // check if media-models.js was enqueued
    ) :
        ?>
            <script>
                // See/copy the FULL code above and place it here..
            </script>
        <?php
    endif;
} );

And if you put the script in an external JS file, you should also ensure that the media-models script has been enqueued:

add_action( 'admin_enqueue_scripts', function () {
    $screen_ids = [ 'post', 'page' ];
    if ( in_array( get_current_screen()->id, $screen_ids ) &&
        wp_script_is( 'media-models' ) // check if media-models.js was enqueued
    ) {
        wp_enqueue_script( 'my-script', '/path/to/my-script.js', [], '', true );
    }
} );

Have you tried this plugin PDF Thumbnails ?

This plugin generates a thumbnail from the first page in the uploaded document and names it as PDFNAME-thumbnail, then you can use this image as a featured image. this plugin is outdated, about 4 years ago so be sure for testing and compatibility.

发布评论

评论列表(0)

  1. 暂无评论