5

I am currently in the process of making a Wordpress gallery that draws directly from the Media Library and incorporates Isotope and Photoswipe. Using a modified version of this, I have successfully added the attachments to a page template and then restricted the display to categories (with categories for media attachments).

My issue now is further refining the display...

As I am using wp_get_attachment_image in my function (so I can define the image size), rather than wp_get_attachment_url, I can't get the href working. In addition to this, I need to define the full image size within the data-size of the href.

I'm also trying to draw the image title and caption, as well as apply the categories of each image as classes to the containing div.

Here is the code I'm using:

function get_images_from_media_library() {
    $args = array(
        'post_type' => 'attachment',
        'post_mime_type' =>'image',
        'post_status' => 'inherit',
        'posts_per_page' => 25,
        'category_name' => 'artwork',
    );
    $query_images = new WP_Query( $args );
    $images = array();
    foreach ( $query_images->posts as $image) {
        $images[]= wp_get_attachment_image( $image->ID, 'full' );
    }
    return $images;
}

function display_images_from_media_library() {

    $imgs = get_images_from_media_library();
    $url = wp_get_attachment_url( $image->ID );
    $image_title = $attachment->post_title;
    $caption = $attachment->post_excerpt;
    $html = '<section class="isotope-wrap">
              <div class="isotope gallery" data-pswp-uid="1">
                <div class="isotope-sizer"></div>';

    foreach($imgs as $img) {
        $html .= '<div class="isotope-item"><figure>
                  <a href="' . $url . '" data-size="">' . $img . '</a>
                  <figcaption class="wp-caption-text"><h2>' . $image_title . '</h2>
                  <p>' . $caption . '</p></figcaption></figure></div>';
    }

    $html .= '</div>';

    return $html;

}

Finally, I'm also trying to build a filter group for the Isotope gallery, using the image categories as the labels. Here is the code I have so far, which doesn't seem to be working since my categories are not counting the images (all categories show a count of 0):

$terms = get_terms('category', array('parent' => 'artwork'));
                      $count = count($terms);
                        if ( $count > 0 ){
                          foreach ( $terms as $term ) {
                            echo "<button type='button' class='btn btn-dark'  data-hover='" . $term->name . "' data-filter='." . $term->slug . "'>" . $term->name . "</button>\n";
                          }
                        }

Any help with this would be greatly appreciated, thanks.

EDIT I added the following code:

function get_image_urls_from_media_library() {
    $args = array(
        'post_type' => 'attachment',
        'post_mime_type' =>'image',
        'post_status' => 'inherit',
        'category_name' => 'artwork',
    );
    $query_images = new WP_Query( $args );
    $urls = array();
    foreach ( $query_images->posts as $image) {
        $urls[]= wp_get_attachment_url( $image->ID );
    }
    return $urls;
}

and added a nested foreach, which is drawing a valid href. Unfortunately, however, it's only drawing the first attachment entry and all images in the gallery are linking to that same first image. The images are also duplicated 5 times on the page.

2

I had a scenario very similar to yours. I trust these notes can help.

1 - When querying a custom taxonomy, wp_query requires a more information. The codex reference is here. The information is in this form.

'tax_query' => array(
        array(
            'taxonomy' => 'people',
            'field'    => 'slug',
            'terms'    => 'bob',
        ),
    ),

In your case, I believe that the taxonomy is "artwork". I found that using the field value of 'slug' is good; I leave it to you to know what your term is.

2 - In your revised function, you dropped the "posts_per_page" parameter. That's your choice but be aware that if you don't declare it then WP-Query will return a maximum of 10 records. If you were expecting more images then this could be the answer.

3 - In your function "display_images_from_media_library", the second line is:

"$url = wp_get_attachment_url( $image->ID );".

In this case, $image is an undefined variable. Since $image is a variable from your function "get_images_from_media_library", I'll hazard a guess that at some stage you had a single function for getting the image information and then displaying it; but when you split the single function into two, you probably didn't notice this line.

4 - Your code to create the filters starts with the top level (the parent level) - that fine, but I believe that the filters are actually the children not the parents. In essence, there's another foreach required (details below).

5 - In addition to the above, you have made your initial focus the "attachment URL". But I suggest it might be more productive to concentrate on getting the post/attachment ID from the WP_Query, and use this as a means to get all the other fields that you need to display. In fact, if you create an array based on $posts, you'll automatically get the caption and the title as a by-product.

I found the following to work. Obviously you need to substitute the relevant Taxonomy and term in each of the functions.

function gallery_get_images_from_media_library(){
    $g_myargs = array(
        'post_type' => 'attachment',
        'post_mime_type' =>'image/jpeg',
        'post_status' => 'inherit',
        'posts_per_page' => 25,
        'tax_query' => array(
            array(
                'taxonomy' => 'media_category',
                'field'    => 'slug',
                'terms'    => 'edition-covers',
            ),
        ),
    );
    $g_myquery_images = new WP_Query( $g_myargs );

    $g_posts = $g_myquery_images->posts;

    $html = '<section class="isotope-wrap">
              <div class="isotope gallery" data-pswp-uid="1">
                <div class="isotope-sizer"></div>';

    foreach ($g_posts as $g_img) {

        $url = wp_get_attachment_url($g_img->ID);

        $src = wp_get_attachment_image_src($g_img->ID,'full');

        $image_title = $g_img->post_title;

        $caption = $g_img->post_excerpt;

        $html .= '<div class="isotope-item"><figure>
                        <a href="'.$url.'">
                        <img src="'.$src[0] .'"></a>
                        <figcaption class="wp-caption-text">
                        <h2>' . $image_title . '</h2>
                        <p>' . $caption . '</p>
                        </figcaption></figure></div>';
    }

    $html .= '</div>';

return $html;
}

To display the images I just added the following code in my template page.

$imgs = gallery_get_images_from_media_library();
echo $imgs;

function gallery_make_filters(){

    // starting row of the filter = show all
    $gallery_filter_content = '<button class="button is-checked" data-filter="*">show all</button>'. PHP_EOL ;

    // get the cover terms for parent terms with a count>0
    $gallery_parentterms = get_terms( array(
    'taxonomy' => 'reviewcovers',
        'parent' => 0,
    'hide_empty' => false,
    ));

    // if there are parent covers with children
    if (is_array($gallery_parentterms)) {

        // break down for each parent
        foreach($gallery_parentterms as $gallery_obj) {

            // get the children covers 
            $gallery_childterms = get_terms( array(
                'taxonomy' => 'reviewcovers',
                'child_of' => $gallery_obj->term_id,
                'hide_empty' => true,
            ));

            // test for content of childterms
            if (is_array($gallery_childterms)) {

            // create a filter for each child.
            foreach($gallery_childterms as $gallery_object) {   

                    // build the filters for each non-zero child term
                    // filter is progressively incremented.
                    $gallery_filter_content .= '<button class="button" data-filter="'.".".$gallery_object->slug.'">'.$gallery_object->description.'</button>'. PHP_EOL;

                } // end of foreach-children array

            } // end of if children array

        } //end of foreach parent array

    }// end of if - parent array
    else 
    {
    echo 'no results';
    }

return $gallery_filter_content;

}

To display the filters, insert the following code in the page template.

$filters = gallery_make_filters();
echo $filters;

Lastly, and not wanting to be accused of 'teaching you how to suck eggs', I find that every so often one or more lines of my code don't work as expected (probably because I am not such a great coder). In any event, when this does happen, I find it useful to display the contents of an array or a variable so that I can work out just where the code is coming undone.

These few lines are my mainstays. I just 'unremark' the lines, update the array/variable name, save, update the site.
1 - for an array

//echo "<pre>";print_r($gallery_childterms);echo "</pre>"; //DEBUG - a readable form of vardump
//echo "<p>end of print_r gallery_childterms</p>"; //DEBUG-this is so I know whether and what has printed.

2 - for a variable

//echo "the src is ".$src."</br>"; // DEBUG - the line break is so that consecutive lines will make sense.
  • Thanks so much for your input -- I trust this worked in your situation. I haven't yet had a chance to implement this into my own, but I will be sure to let you know the outcome once I do get a chance. You've given a lot of detail and, addressing your final point of 'teaching me to suck eggs', I could never accuse you of such, since I'm still feeling my way through this confusing language they call PHP. – Ash Aug 24 '18 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.