Jump to content

[SOLVED] How to define a simple gallery region ?


happywire
 Share

Recommended Posts

[solution]

========================================================

I made a simple gallery-page.php template with following code.

<?php namespace ProcessWire;

// gallery-page.php template file

$content = $page->images;

if (count($page->images)) {

    // the page has one or more images
    foreach ($page->images as $image => $value) {
        echo $value;
        echo "picture markup to follow..";
    }
}

Ideally this should be output via the _main.php output file.

<!-- main content -->
<div id='content'>
    <h1><?php echo $title; ?></h1>
    <?php echo $content; ?>
</div>

Having it like above inserts the image urls and the text "picture markup.. " right at the top of the page and then only the image urls inside the Gallery section of the page. I understand why this happens. $content is once defined as $page-> image; but the if(count.. condition is inserted directly at the top of the page because it is not delyed output any more.

Now when I try to do

<?php namespace ProcessWire;

// gallery-page.php template file

$content = if (count($page->images)) {

    // the page has one or more images
    foreach ($page->images as $image => $value) {
        echo $value;
        echo "picture markup to follow..";
    }
}

naturally it throws an error.

How can I have the template code that I want to be stored inside the $content variable please?

So something like $content = and then put all my code that I like for the images to be in that?

Link to comment
Share on other sites

You mean something like this?


$content = $page->images;

if (count($page->images)) {

    // the page has one or more images
    foreach ($page->images as $image => $value) {
        $content .= $value;
        $content .= "picture markup to follow..";
    }
}

 

  • Like 1
Link to comment
Share on other sites

Yes, that is it. So simple! Thank you heaps. That will get me going.

I did search in the forums and docs/tuts.
Do you have good resources for me to follow through with delayed output with regards to making proper responsive images.

On my list is this.

1. Define image sizes and upon upload have ProcessWire create those.
a) Return the array of all created image urls.
b) Ideally create webp versions of those images as well.
For webp support I found this

 

2. In the end I would like to write a function that I can include in a region that will output proper responsive image syntax similar to this.

<picture class="pic-id-578 projects-picture"
  ><source
    sizes="(min-width: 1700px) 469px,
        (min-width: 1200px) 27.71vw,
        (min-width: 780px) calc(50vw - 80px),
        (min-width: 640px) calc(50vw - 24px),
        calc(100vw - 32px)"
    srcset="
      https://example.com/picture-640x427.webp 640w,
      https://example.com/picture-525x350.webp 525w,
      https://example.com/picture-425x284.webp 425w,
      https://example.com/picture-320x214.webp 320w,
      https://example.com/picture-240x160.webp 240w,
      https://example.com/picture-180x120.webp 180w
    "
    type="image/webp"
  />
  <img
    class="lazyload"
    src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
    data-src="https://example.com/picture-320x214.jpg"
    alt="Some useful alternative text"
    sizes="(min-width: 1700px) 469px,
        (min-width: 1200px) 27.71vw,
        (min-width: 780px) calc(50vw - 80px),
        (min-width: 640px) calc(50vw - 24px),
        calc(100vw - 32px)"
    data-srcset="https://example.com/picture-640x427.jpg 640w,
        https://example.com/picture-525x350.jpg 525w,
        https://example.com/picture-425x284.jpg 425w,
        https://example.com/picture-320x214.jpg 320w,
        https://example.com/picture-240x160.jpg 240w,
        https://example.com/picture-180x120.jpg 180w"
  />
</picture>

Coming from WP I did write this function.

<?php
function responsive_picture($acf_image_array, $media_condition, $type)
{

    // Get the global $theme_name_pagename variable
    global $theme_name_pagename;
    // var_export( $theme_name_pagename );

    // Get the global $theme_name_category_slug variable
    global $theme_name_category_slug;
    // var_export( $theme_name_category_slug );

    // Get the global $theme_name_custom_post_type_slug variable from archive.php
    global $theme_name_custom_post_type_slug;
    // var_export( $theme_name_custom_post_type_slug );

    // Make an array where the sources for the image will be placed
    $sources = array();
    // If the field for the post/page/cpt is filled then do stuff, otherwise don't
    if ($acf_image_array) {
        foreach ($acf_image_array['sizes'] as $image_size_key => $image_size_value) {
            if (preg_match('/^(\d+)$/', $image_size_key)) {
                if (preg_match('/-' . $image_size_key . 'x\d+\.(jpeg|jpg|png)$/i', $image_size_value)) {
                    array_push(
                        $sources,
                        array(
                            'width'  => $image_size_key,
                            'height' => $acf_image_array['sizes'][$image_size_key . '-height'],
                            'src'    => $image_size_value,
                        )
                    );
                }
            }
        } // end foreach ( $acf_image_array['sizes'] as $image_size_key => $image_size_value )
        // http://php.net/manual/en/function.array-reverse.php
        // $sources = array_reverse( $sources );
        // return var_export( $sources );
        // exit;
        $srcset = array();
        foreach ($sources as $index => $source_values) {
            array_push($srcset, $source_values['src'] . ' ' . $source_values['width'] . 'w');
        }
        $srcset = implode(', ', $srcset);

        // preg_replace .jpg with .webp
        // http://php.net/manual/en/function.preg-replace.php
        $srcset_webp = $srcset;
        $pattern     = '/.jpg /';
        $replacement = '.webp ';
        $srcset_webp = preg_replace($pattern, $replacement, $srcset_webp);
        // var_export($srcset_webp);

        // Depending on the post, page or custom post type, set the picture class accordingly
        if (null !== $theme_name_pagename) {
            // echo esc_html( $pagename );
            print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' page-' . esc_html($theme_name_pagename) . '-picture">';
        }
        if (null !== $theme_name_category_slug) {
            // echo esc_html( $category_slug );
            print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' category-' . esc_html($theme_name_category_slug) . '-picture">';
        }
        if (null !== $theme_name_custom_post_type_slug) {
            // var_export( esc_html( $post_type ) );
            // var_export( $theme_name_custom_post_type_slug );
            // https://codex.wordpress.org/Function_Reference/is_post_type_archive
            // Differentiate between single- and archive-
            if (is_post_type_archive($theme_name_custom_post_type_slug)) {
                // print 'is_post_type_archive';
                print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' archive-' . esc_html($theme_name_custom_post_type_slug) . '-picture">';
            } else {
                print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' single-' . esc_html($theme_name_custom_post_type_slug) . '-picture">';
            }
        } else {
            // null === $theme_name_custom_post_type_slug
            // var_export( $theme_name_custom_post_type_slug );
            $post_type = get_post_type();
            if ('' !== $post_type && 'page' !== $post_type) {
                $post_type_data = get_post_type_object($post_type);
                $theme_name_custom_post_type_single_slug = $post_type_data->rewrite['slug'];
                // var_export( esc_html( 'single ' . $theme_name_custom_post_type_single_slug ) );
                print '<picture class="pic-id-' . esc_html($acf_image_array['id']) . ' single-' . esc_html($theme_name_custom_post_type_single_slug) . '-picture">';
            }
        }

        // This part of the function is for the webp file format START ;)
        print '<source ';
        // print 'sizes="' . esc_html( $media_condition . $viewport ) . '" '; // leave space between attributes
        print 'sizes="' . esc_html($media_condition) . '" '; // leave space between attributes
        print 'srcset="' . esc_html($srcset_webp) . '" '; // leave space between attributes
        print 'type="image/' . esc_html($type) . '">'; // either webp or jp2 and close <source> here
        // This part of the function is for the webp file format END ;)

        // Default loading
        // print '<img ';
        // print 'src="' . esc_html( $acf_image_array['sizes'][320] ) . '" '; // default image size leave space between attributes
        // print 'alt="' . esc_html( $acf_image_array['alt'] ) . '" '; // leave space between attributes
        // print 'sizes="' . esc_html( $media_condition ) . '" '; // leave space between attributes
        // print 'srcset="' . esc_html( $srcset ) . '">'; // close img tag here
        // print '</picture>';
        // With lazysizes
        print '<img class="lazyload" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" '; // leave space between attributes
        print 'data-src="' . esc_html($acf_image_array['sizes'][320]) . '" '; // default image size leave space between attributes Alternatively you can simply define a fallback src via the data-src attribute.
        print 'alt="' . esc_html($acf_image_array['alt']) . '" '; // leave space between attributes
        print 'sizes="' . esc_html($media_condition) . '" '; // leave space between attributes
        print 'data-srcset="' . esc_html($srcset) . '">'; // close img tag here
        print '</picture>';
    }
}

In a template I would then go on to call that function for example with the following arguments.

<?php
// Get the array values for the field responsive_picture for the current post
$responsive_picture_array = get_field( 'responsive_picture' );
responsive_picture( $responsive_picture_array, '(min-width: 1700px) 469px, (min-width: 1200px) 27.71vw, (min-width: 780px) calc(50vw - 80px), (min-width: 640px) calc(50vw - 24px), calc(100vw - 32px)', 'webp' );
?>

So that is my aim really that I am working towards.
Once they all check out with this https://github.com/ausi/respimagelint I will be satisfied.

Any sections in the forums/docs/tuts/api/recepies that you can think of, kindly fire away, thank you.

Link to comment
Share on other sites

I guess you may keep the srcset creation in your function as is with very few changes.

Add some output variable at the head of your function, something like this:

function responsive_picture($acf_image_array, $media_condition, $type)
{
	$out = '';

Replace each print with $out .= like this:

        $out .= '<img class="lazyload" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" '; // leave space between attributes
        $out .= 'data-src="' . esc_html($acf_image_array['sizes'][320]) . '" '; // default image size leave space between attributes Alternatively you can simply define a fallback src via the data-src attribute.
        $out .= 'alt="' . esc_html($acf_image_array['alt']) . '" '; // leave space between attributes
        $out .= 'sizes="' . esc_html($media_condition) . '" '; // leave space between attributes
        $out .= 'data-srcset="' . esc_html($srcset) . '">'; // close img tag here
        $out .= '</picture>';
   

End your function with

	return $out;
}

What you need to do is either creating the $acf_image_array from the PW image before calling the function (keep its API), or change the function to parse the media conditions and create matching variants as required (given a single image).

Either way you'll do something like $imgVariant = $img->size($variantWidth, $variantHeight) for each required size.

  • Thanks 1
Link to comment
Share on other sites

2 hours ago, Autofahrn said:

What you need to do is either creating the $acf_image_array from the PW image before calling the function (keep its API)

This. I certainly need to create an image_array of all image variations and store that in the db.

Found this topic.

Alongside https://processwire.com/blog/posts/processwire-3.0.10-expands-image-resize-options/ and this part of the docs https://processwire.com/api/ref/pageimage/ .

Now when I include something like this, having installed the ImageMagick module as per this post https://processwire.com/blog/posts/processwire-3.0.10-expands-image-resize-options/

<?php namespace ProcessWire;

// gallery-page.php template file

$content = ""; // $page->images;

if (count($page->images)) {

    // the page has one or more images
    foreach ($page->images as $image) {

        // http://cheatsheet.processwire.com/files/image-methods/image-size-width-height-options/

        // $defaultOptions = array( 'upscaling' => true, 'cropping' => true, 'quality' => 90 );

        // $image->size($width, $height, $options)

        $defaultOptions = array(
            'upscaling' => false,
            'cropping'  => false,
            'quality'   => 100
        );

        $img_size_9000 = $image->size(9000, 0, $defaultOptions);
        $img_size_8400 = $image->size(8400, 0, $defaultOptions);
        $img_size_8000 = $image->size(8000, 0, $defaultOptions);
        $img_size_7680 = $image->size(7680, 0, $defaultOptions);
        $img_size_6000 = $image->size(6000, 0, $defaultOptions);
        $img_size_5400 = $image->size(5400, 0, $defaultOptions);
        $img_size_4096 = $image->size(4096, 0, $defaultOptions);
        $img_size_3840 = $image->size(3840, 0, $defaultOptions);
        $img_size_3200 = $image->size(3200, 0, $defaultOptions);
        $img_size_2560 = $image->size(2560, 0, $defaultOptions);
        $img_size_2048 = $image->size(2048, 0, $defaultOptions);
        $img_size_1920 = $image->size(1920, 0, $defaultOptions);
        $img_size_1600 = $image->size(1600, 0, $defaultOptions);
        $img_size_1280 = $image->size(1280, 0, $defaultOptions);
        $img_size_1140 = $image->size(1140, 0, $defaultOptions);
        $img_size_1024 = $image->size(1024, 0, $defaultOptions);

        $img_size_960 = $image->size(960, 0, $defaultOptions);
        $img_size_900 = $image->size(900, 0, $defaultOptions);
        $img_size_800 = $image->size(800, 0, $defaultOptions);
        $img_size_768 = $image->size(768, 0, $defaultOptions);
        $img_size_640 = $image->size(640, 0, $defaultOptions);
        $img_size_525 = $image->size(525, 0, $defaultOptions);
        $img_size_425 = $image->size(425, 0, $defaultOptions);
        $img_size_320 = $image->size(320, 0, $defaultOptions);
        $img_size_240 = $image->size(240, 0, $defaultOptions);
        $img_size_180 = $image->size(180, 0, $defaultOptions);

        $content .= "<a href=" . $img_size_9000->httpUrl . ">$img_size_9000->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_8400->httpUrl . ">$img_size_8400->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_8000->httpUrl . ">$img_size_8000->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_7680->httpUrl . ">$img_size_7680->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_6000->httpUrl . ">$img_size_6000->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_5400->httpUrl . ">$img_size_5400->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_4096->httpUrl . ">$img_size_4096->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_3840->httpUrl . ">$img_size_3840->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_3200->httpUrl . ">$img_size_3200->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_2560->httpUrl . ">$img_size_2560->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_2048->httpUrl . ">$img_size_2048->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_1920->httpUrl . ">$img_size_1920->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_1600->httpUrl . ">$img_size_1600->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_1280->httpUrl . ">$img_size_1280->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_1140->httpUrl . ">$img_size_1140->httpUrl</a>" .  "</br>";
        $content .= "<a href=" . $img_size_1024->httpUrl . ">$img_size_1024->httpUrl</a>" .  "</br>";

        $content .= "<a href=" . $img_size_960->httpUrl .  ">$img_size_960->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_900->httpUrl .  ">$img_size_900->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_800->httpUrl .  ">$img_size_800->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_768->httpUrl .  ">$img_size_768->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_640->httpUrl .  ">$img_size_640->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_525->httpUrl .  ">$img_size_525->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_425->httpUrl .  ">$img_size_425->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_320->httpUrl .  ">$img_size_320->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_240->httpUrl .  ">$img_size_240->httpUrl</a>" . "</br>";
        $content .= "<a href=" . $img_size_180->httpUrl .  ">$img_size_180->httpUrl</a>" . "</br>";
    }
}

and upload for example following image

https://fee.org/media/24571/nasa_space_outer_universe-min.jpg

and that being 7857 × 7462 pixels wide I get the following.

1. The image variations are not created during file upload in the backend. They are created only when I visit the Gallery page on the frontend. How can I create the image variations when uploading in the backend without touching the frontend? Doing this locally is not an issue, though if this is being done on the live site it won't be good. First time I loaded the Gallery page it crashed the local server, on 2nd load it would display the image variation links.

2. Each time I reload the Gallery page it does take some time to load, considerably more than usual (1-2 seconds), I assume this is due to the $image->size method being called and added to $content for each image size and this happens each time the page loads.

3. Despite the $defaultOptions set to upscaling=>false there are still httpUrls created for image variations larger than the original image. How can I only get httpUrls for image variations that are not larger than the original image? So in this example I would expect to only get httpUrl up to 7680px width.

19 minutes ago, louisstephens said:

I have not implemented this yet for myself, but I did stumble across this in my bookmarks. It looks promising with srcset etc.

 

Thank you. I will have a look at this right this moment, still trying to figure out how to create image variations in the backend/admin panel rather than on first time of page load.

Link to comment
Share on other sites

28 minutes ago, louisstephens said:

I have not implemented this yet for myself, but I did stumble across this in my bookmarks. It looks promising with srcset etc.

 

That approach/code uses art direction as opposed to changing image sizes. When I started learning responsive images I also went for that approach thinking that having different source tags meant that each different source is a different size of the same image. Have a look at this detailed post https://dev.opera.com/articles/responsive-images/ . That code in the post you linked uses the "Changing image sizes, high-DPI images & art direction use case". It means that when you resize the browser window not the same image at a different size will be shown but a completely different one, one that you choose to show. This also means that when you resize that source will be downloaded again and again as you keep resizing, more requests, bad performance.

However I do not have the need for art direction. I am after responsive images, the same identical image, albeit with a different size where I let the browser decide what version is best for the given viewport. That is the last example in that post I linked, the "Changing image sizes, high-DPI images & different image types use case". Like this, for example once you go from wide viewport to narrow, i.e. landscape to portrait, the smaller size of the image will only be downloaded once. When you go back into landscape mode the wider image is cached and not re-downloaded. To make all this more fun, different browsers handle this differently. If what I write does not make sense read through the 10 parts starting here https://cloudfour.com/thinks/responsive-images-101-definitions/ . That really helped me understand it properly.

Link to comment
Share on other sites

@louisstephens In that thread you linked

I found

and since I cannot edit my above post I meant that in fact the source from the later , "srcset, sizes and picture support" uses art direction instead of sizes and dpi, however I also read through the MarkupSrcSet thread and it does not seem correct to me at least, however I might be able to look into that repo to learn how image variations are created server-side so that I can have an image array to work with without affecting the frontend.

If you are unsure, test the output with https://ausi.github.io/respimagelint/ it is the definite answer to having correct syntax when it comes to responsive images, be this using art direction or sizes.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...