How to limit Query Loop on Media Gallery to current post's medias (custom field)?

[EDIT] I am moving this from How To to Bugs since it seems to me that I have followed the tutorial as mentioned, and that the behavior of the results from the Image Media Query is not right. In my case, the query keeps on pulling and showing the data from the last published post, instead of the content related to the current post.

I have followed the tutorial here : Query Loop – Bricks Academy

And thought I could use this on a Single template for a CPT. But the query will show all medias in the media library.

How could I limit this to the medias inserted in a custom field linked to that CPT’s single template ?

Thanks.

I’m not sure if I understand it correctly but I guess you need to add your custom post type here instead of “media”.

I have managed to somehow stop the fact it was loading ALL medias from the entire Media content, but I now have another problem : even after following instructions given here Query Loop – Bricks Academy for the Media Query > Example 2: Media Gallery, the images that are shown do not correspond to the current post. They somewhat correspond to the latest created post, which means that all the Single Templates for this CPT will show the same content (the last created post) instead of it’s own content posted in the backend (a MetaBox custom field of “Image Advanced” type), which is obviously wrong.

This is my setup for the query loop on the Block inside the Container (as instructed)

Capture d’écran 2022-11-30 à 17.25.47

This is my setup for the Image element (as instructed) :

Are you trying this kind of functionality? Creating the gallery page with the Bricks editor - BricksUltimate

It is made with ACF. But you can make the same thing with Metabox image advanced.

Not sure what your example does (what do you mean by 'the Gallery Page", what Gallery for what type of Post/Page ?).

I have a gallery-type custom field for each of my Posts (CPT), where the client ca upload a gallery of photos.

That Gallery must therefore be displayed with it’s own content on the Single Template.

The problem I am facing is that the Query Loop for Media type does not seem to work properly when trying to use it for the content of the current post.

I can’t use the native Bricks Image Gallery element since it does not provide enough options (somehow Grid only offers strange image ratios (square, 4:3, 16:9, … what about 2:3 the most common photo ratio ???)

Yes. I am saying that.

You will create the CPT. Then create the gallery custom fields with the MetaBox for that CPT. Client or user will upload the images to every CPT post. Next, I shall create the template(single cpt post page) and use my custom wp-query provider which will fetch the images of that CPT and display them in the grid layout. Done.

OK, I did not understand you had made a custom query provider. Unfortunately I do not own Bricks Ultimate…
Thanks for your explanations in any case.

That’s fine. You do not need the BricksUltimate. You can do it yourself with PHP knowledge. I think that you do not need the pagination for the gallery items right?

I did this for a single page. But you can apply the same procedure for your single CPT template. Please check the video for the idea Creating gallery section with Meta Box and Bricks - YouTube

So I don’t know how to make this work. There is apparently no way to make the native Media attachment query loop pull the right images. It always uses the photos of the requested custom field, but always and only the ones that have been added to the last created post… no idea why it’s not just pulling from the current post, given it is a Single Template, the query should be for current ID, shouldn’t it ?

@timmse maybe ?

I’m going to share this for the community and hoping this gets better along the way. I was trying to query the medias uploaded to a post through a custom field (Metabox/Advanced Images) and display them in a Gallery using the Bricks query loop for Medias (Query Loop – Bricks Academy). But since the images are not automatically attached to the current post they are being uploaded to (it is acknowledged by Metabox support), the query using “child of : {post_id}” does not work.

I have found out there are two steps necessary :

#1 Amend Query Post_in For Gallery (given by Bricks support), replace “mg_projet_galerie_images” by your own custom field and “yeamho” by the ID of your element with the query loop. Using this technique, you do NOT set “child of: {post_id}”, you leave it blank :

<?php 

add_filter( 'bricks/posts/query_vars', function( $query_vars, $settings, $element_id ) {

    if ( $element_id !== 'yeamho') return $query_vars;
        
    $gallery_images = (array) rwmb_meta( 'mg_projet_galerie_images', ['size' => 'full'] );
    $gallery_images_ids = array_keys($gallery_images);
    
    // if no gallery images, set empty string array
    $gallery_images_ids = count($gallery_images_ids) > 0 ? $gallery_images_ids : [''];
    
    $query_vars['post__in'] = $gallery_images_ids;

    return $query_vars;
}, 10, 3 );

#2 Make sure the uploaded media attachments are automatically attached to the current post they uploaded to (replace “mg_projet_galerie_images” by your own custom field). It appears for me I do not necessarily need to set the query loop (media type) to “child of: {post_id}” as explained in the Bricks academy tutorial. To automatically attach/detach images to the post use this code (edit : replace with newer one below) :

<?php

add_action('save_post', 'update_image_data');

function update_image_data($post_id){
    $images = get_post_meta($post_id, 'mg_projet_galerie_images', true);
    if(!empty($images)){
        foreach($images as $image){
            wp_update_post(array('ID' => $image, 'post_parent' => $post_id));
        }
    }
}

Now to make this better, I have to find a way to remove (un-attach) the medias if removed from the current post. I hope this will help some of you.

EDIT 2023/01/13 : I found the way to automatically attach & detach images from post when removed from the custom field (MetaBox Advanced Image) :

<?php
add_action('save_post', 'update_detach_image_data');

function update_detach_image_data($post_id) {
    $current_images = get_post_meta($post_id, 'mg_projet_galerie_images', false);
    if(!empty($current_images)){
        foreach($current_images as $current_image){
            wp_update_post(array('ID' => $current_image, 'post_parent' => $post_id));
        }
    }

    $query_args = array(
        'post_type' => 'attachment',
        'post_parent' => $post_id,
        'post_status' => 'any',
        'posts_per_page' => -1,
        'fields' => 'ids',
        'no_found_rows' => true
    );
    $attachments_query = new WP_Query($query_args);
    $attachments = $attachments_query->posts;

    $detach_images = array_diff($attachments, $current_images);
    if (!empty($detach_images)) {
        foreach ($detach_images as $detach_image) {
            wp_update_post(array('ID' => $detach_image, 'post_parent' => 0));
        }
    }
}
1 Like

Hey AnLip,

thanks for your snippet!

Since you have come so far I must ask you this:

I only want to display the images within my custom field (image advanced / metabox). Since I am using a Recipe Plugin where you can upload further images for the recipe steps, they are also being attached to the media array. Can I somehow filter them out with the meta query?

Thank you so much for your time providing your code up there!

Best wishes!

Hi,
I have updated the code with the newer snippets I figured out (with the help of chatGPT). There is now a snippet that automatically attaches & detaches images from the post they have been added to, and it works smoothly. There might be limitations to this, such as if the image is added in two distinct custom fields, removed from one, will it stay in the other ? I don’t know.
Nevertheless I am not sure how your recipe plugin adds images. I would say that if your images are added to a distinct custom field (distinct database table), then it shouldn’t mingle with the ones you added.
But have you tried it and can affirm that they do mingle ? If so, I’m afraid I can’t help your further. Good luck.

1 Like

Hey, understand. Then I will continue to investigate. Thanks for you reply! :+1:

SOLVED

After AnLips code works. Be sure that you use the auto generated element ids. Custom ids do not work.

Thank you!

Greetings all,

I came across this post via the Facebook page.
I think there is a solution to my problem somewhere in this code…
I have an image gallery created in Metabox which I’m trying to query in a loop using Bricks Slider (nestable) on a page, not a template with no luck so far.
It seems the above code may be my saviour - my question is…
Can this work on a page and not a template?

Thanks,
Gavin

Did you make it to work on your slider?

/// EDIT 2024/03/05 : I have rewritten it all here hopefully it works for you //

#1 Add this snippet that will Attach Images to the Current Post (they are added to) somewhere (snippet manage or child-theme). It will make sure that when you add an image to a Gallery type custom field to a Post, it will attach these medias to the post.

<?php
add_action('save_post', 'update_detach_image_data');

function update_detach_image_data($post_id) {
    $current_images = get_post_meta($post_id, 'my_gallery_field_id', false);
    if(!empty($current_images)){
        foreach($current_images as $current_image){
            wp_update_post(array('ID' => $current_image, 'post_parent' => $post_id));
        }
    }

    $query_args = array(
        'post_type' => 'attachment',
        'post_parent' => $post_id,
        'post_status' => 'any',
        'posts_per_page' => -1,
        'fields' => 'ids',
        'no_found_rows' => true
    );
    $attachments_query = new WP_Query($query_args);
    $attachments = $attachments_query->posts;

    $detach_images = array_diff($attachments, $current_images);
    if (!empty($detach_images)) {
        foreach ($detach_images as $detach_image) {
            wp_update_post(array('ID' => $detach_image, 'post_parent' => 0));
        }
    }
}

#2 Also add this snippet (that will add a filter to modify the query variables for specific element IDs). Make sure to change the loop ID(s) - I had 3 loops on the same template - and the custom fields to your own :

<?php
// Add a filter to modify the query variables for specific element IDs
add_filter(
    "bricks/posts/query_vars",
    function ($query_vars, $settings, $element_id) {
        // Define the target element IDs that we want to modify the query for
        $target_element_ids = ["yeamho", "sbcczz", "xsizky"];

        // If the current element ID is not in the target element IDs, return the query_vars unchanged
        if (!in_array($element_id, $target_element_ids)) {
            return $query_vars;
        }

        // Retrieve the gallery images attached to the current post and cast the result as an array
        // 'mg_projet_galerie_images' is the custom field that stores the gallery images
        $gallery_images = (array) rwmb_meta("my_gallery_field_id", ["size" => "full"]);

        // Extract the IDs of the gallery images using array_keys function
        $gallery_images_ids = array_keys($gallery_images);

        // Modify the query_vars to include only the gallery image IDs
        // If $gallery_images_ids is empty, set the query_vars "post__in" parameter to an array containing an empty string
        $query_vars["post__in"] = $gallery_images_ids ?: [""];

        // Return the modified query_vars
        return $query_vars;
    },
    10, // Priority of the filter
    3   // Number of arguments accepted by the callback function
);

#3 Then you need to set your loop to :

  • type : Posts
  • post type : media
    (optional) - order by : post include order
    (optional) - order : ascending
    (optional) - posts per page : -1

#4 On the (Bricks) Image element inside the loop, set it to {post_id}

That should make it work, as it works for me on my projects. Please let me know if it doesn’t work for you.


Capture d’écran 2024-03-05 à 18.00.13