Textpattern tips, tutorials and code snippets

Accessible image display

There are many third-party solutions like Shadowbox, Fancybox, Royal Slider, PhotoSwipe etc which display series of images with great style and pzazz on some devices but not usually on all devices. For example, they may use overlays and jQuery so that clicking a thumbnail shows the full photo overlaid over the same page along with beautiful transitional effects. Unfortunately this can make the photos inaccessible on some devices because navigation buttons are hidden from touch screens and the browser ‘back’ button takes you away from the thumbnails. So I wanted a way to go from the thumbnail to the full image displayed in a new page so the ‘back’ button and navigation were always accessible. I also wanted to be able to display all sizes of image and it still look OK.

With some nudging and help on the TXP forum from Joe, Jakob, Marc Carson, Adi Gomedia, Matt Davis, Oleg etc and Jukka Gocom I found a way to do what I want just with Textpattern, some coding and some plugins. I am not a coder (I didn’t have a clue as to whether it was even possible) so thank you very much guys! Textpattern coders rule!

Simple browser ‘back’ button method

First, install adi_gps plugin which extracts variables from a URL.

Second, create a new section called “Photos” that will display the images.

Third, in an article form, create the list of thumbnails and links from each to pass the image ID and image category to the Photos page (my page titles were the same as my image categories). Like so:

<txp:images sort="id asc" break="" category='<txp:article_url_title />'>
<txp:if_different>
<a href="<txp:site_url />photos/?pic=<txp:image_info type="id" />&cat=<txp:article_url_title />"><txp:thumbnail /></a>
</txp:if_different>
</txp:images>

Fourth, using adi_gps, extract the pic and cat variables from the incoming URL and use them to display the desired image and caption. Like so:

<txp:adi_gps name="pic,cat" />
<txp:images id='<txp:variable name="pic" />' category='<txp:variable name="cat" />'>
<div><p><txp:image_info type="caption" /></p><txp:image /></div>
</txp:images>

That’s it! Image and caption are accessible on all devices and the browser’s back button is used for navigation. The Photos page can be styled to your liking so it looks good too.

Improve the navigation

A link back from the full image to the thumbnail page helps. I did the following but it has security problems so abandoned it. Don’t use this but I include it for your information.

<a href="<txp:php> echo $_SERVER['HTTP_REFERER'];</txp:php>">Back</a>

People are used to one-click navigation between sets of photos nowadays so how can we do that? The first way used adi_calc and smd_lately plugins but the ‘back’ button is needed when there are non-consecutive image IDs and Visitor Logs need to be on for smd_lately to find the correct back links. Read about that method here.

Thanks to the guys above, there is a method that does not rely on Visitor Logs being on and will also find non-consecutive images. It uses a cookie escaped with htmlspecialchars for security and etc_query plugin for true next/prev image links. Perfect? Sadly, no. The cookie has security problems too being vulnerable to PHP injections that can destroy all data. Thanks, Jukka for your security expertise and for looking out for us on the Textpattern forum.

The following may not be the final solution but it does not use a cookie, it works, it is safe, it is accessible on all devices, the browser back button works as expected and it can display any size of image. You can style the page any way you like and could even add jQuery effects if you like.

The solution

The code for the Photos page is now like this:

<txp:adi_gps name="pic,cat" />
<txp:images limit="1" id='<txp:variable name="pic" />' category='<txp:variable name="cat" />'>
   <div><p class="imgnav">

        <txp:variable name="imgnav">
             <txp:images sort="id asc" break="" category='<txp:variable name="cat" />'><a href='<txp:site_url />photos/?pic=<txp:image_info type="id" />&cat=<txp:variable name="cat" />' data-id='<txp:image_info type="id" />'><txp:thumbnail /></a>
             </txp:images>
         </txp:variable>

              <txp:etc_query data='<txp:variable name="imgnav" />'  query="a[@data-id='{?pic}']">
  {preceding-sibling::a[1]}
  <txp:smd_lately exclude="host:like:photos" by="" wraptag="" break="span" limit="1">
    <txp:permlink>Leave gallery</txp:permlink>
  </txp:smd_lately>
  {following-sibling::a[1]}
</txp:etc_query>

     <txp:smd_lately exclude="host:like:photos" by="" wraptag="" break="span" limit="1">
<txp:permlink>Leave gallery</txp:permlink>
     </txp:smd_lately>

     </p>
     <p class="caption"><txp:image_info type="caption" /></p>
         <txp:image />
   </div>
</txp:images>

In the above, adi_gps grabs the image variables; txp:images uses those variables; imgnav variable gets the data needed for etc_query; etc_query#1 finds and displays a previous link; smd_lately provides a link directly to the originating thumbnail page; etc_query#2 finds and displays a next link; image_info displays the caption; and txp:image displays the full-size image. The etc_query is split for styling purposes so that the order can be prev, back (to starting page), next.

9 Comments Comment feed

This tutorial has been updated today as the cookie method outlined had some security implications. Thanks to Jukka for pointing this out.

If smd_lately does not fit the bill for you because of Visitor Logs having to be on, I found an alternative. You can read about it on the forum but it is peculiar to my setup where my image categories are the same as the url_titles. But it might give some clue to help with your own setup.

Spelt my last name wrong but thanks for the mention. Glad I was helpful!

@MattD – changed to Davis! Sorry about that…..!

  • etc
  • 12 June 2012

You do not have to (actually shouldn’t) split etc_query, since it can be used as container:

<txp:etc_query data='<txp:variable name="imgnav" />'  query="a[@data-id='{?pic}']">
  {preceding-sibling::a[1]}
  <txp:smd_lately exclude="host:like:photos" by="" wraptag="" break="span" limit="1">
    <txp:permlink>Leave gallery</txp:permlink>
  </txp:smd_lately>
  {following-sibling::a[1]}
</txp:etc_query>

Thanks for improving the code Oleg, and thanks for correcting my spelling mistake, Jonathan.

Zero - would you like me to update the tip and place etc’s new code before the call to smd_lately?

  • etc
  • 13 June 2012

Zero, Jonathan – the only reason is that parsing large data (like 10000 image links) can be time-consuming, so we’d better avoid doing it twice. The difference would hardly be noticeable (~0.005s), but let keep it green.

Thanks @etc – I’ve updated the above code as per your request. Any changes – let me know. Thanks!

Add a comment

Use Textile help to style your comments