zanona
zanona

Reputation: 12717

Tumblr theme dev: Square-75px photos for Photoset posts

I am trying to use Tumblr's Theme API and just found out that for Photoset posts the variable {PhotoURL-75sq} (which should be inside block:Photos won't return a value. It works ok for single photo posts but not for Photosets.

Also it seems that the picture itself gets generated but the API doesn't return a proper value for example:


(source: tumblr.com)

the images above where uploaded into a photoset post using tumblr control panel, and as you can see, by just replacing the end of the filename 250px image with 75sq it shows up correctly (which means it was indeed generated).

http://28.media.tumblr.com/tumblr_lzvey54yzV1ro516ho2_75sq.jpg

but when using `{PhotoURL-75sq}', it won't return it's value.

{block:Photoset}
    <h1>{TimeAgo}</h1>
    <div class='slideshow'>
        {block:Photos}
            <img src='{PhotoURL-75sq}' alt>
        {/block:Photos}
    </div>
{/block:Photoset}

I am not sure if this is the right place to be asking for this but since their support refuses to help me by saying:

Unfortunately, we can't provide technical support for HTML customizations. Given our large number of users, we just don't have the resources. Our apologies. If you'd like to learn more about HTML and CSS...

Where in this case I am thinking that or this is a bug or they simply renamed that variable when it's inside a Photoset without letting the developers know about it.

Thanks in advance

Upvotes: 1

Views: 1541

Answers (2)

Tyler Daniel
Tyler Daniel

Reputation: 676

I was a little concerned about the browser unnecessarily loading the 250px images, so I did it a little differently. Of course, I know almost nothing about javascript, so, fwiw:

Somewhere in the head or body (where it won't be repeated):

  <script type="text/javascript">
    var img_75sq = function(imgTag, urlFor250px)
    {
       var urlFor75px = urlFor250px.replace('_250.jpg', '_75sq.jpg');
       var newImgTag = imgTag.replace('SRC', 'src="' + urlFor75px + '"');
       document.write(newImgTag);
    }
  </script>

And then:

    {block:Photoset}
       {block:Photos}
           <script type="text/javascript">
             img_75sq('<img id="..." style="..." SRC>', '{PhotoURL-250}');
           </script>
       {/block:Photos}
    {/block:Photoset}

This way the browser never sees 250px img tags. The simplicity also suits my novice DOM/JS skills. :)

Upvotes: 1

Ally
Ally

Reputation: 1922

In your head add this:

<script type="text/javascript">
function resizePhotosets(desiredSize)
{
    var setFrames = document.getElementsByClassName("photoset");
    if (setFrames != null)
    {
         for(var i = 0; i < setFrames.length; i++)
         {  
             var foundWindow = false;
             var frameWindow = null;

             while(!foundWindow)
             {
                 frameWindow = setFrames[i].contentWindow;
                 if (frameWindow != null)
                     foundWindow = true;
             } 

             var foundDoc = false;
             var frameDoc = null;

             while(!foundDoc)
             {
                 frameDoc = frameWindow.document;
                 if (frameDoc != null)
                     foundDoc = true;
             }

             if (foundDoc)
             { 
                 var photoRows = frameDoc.body.getElementsByClassName("photoset_row");
                 for (var j = 0; j < photoRows.length; j++)
                 {
                     photoRows[j].removeAttribute("style");
                     photoRows[j].style.display = "inline";
                     var photos = photoRows[j].getElementsByTagName("img");
                     for(var k = 0; k < photos.length; k++)
                     {
                         photos[k].style.width = desiredSize.substring(0, desiredSize.lastIndexOf('sq')) + 'px';
                         var source = photos[k].src;
                         var pos1 = source.lastIndexOf('_');
                         var pos2 = source.lastIndexOf('.');
                         photos[k].src = source.substring(0, pos1 + 1) + desiredSize + source.substring(pos2);
                     }
                }    
            }
        }
    }
    return false;
}


</script>

And then call it from your body tag like this: <body onload="resizePhotosets('75sq')">

The script does the following...

  1. When the document has loaded, check if there are photoset frames on the page. If there are photoset frames on the page, continue. Otherwise, do nothing.
  2. For each photoset frame, wait for the frame window and frame document to load.
  3. As soon as the frame document has loaded, grab all of the photoset rows.
  4. For each photoset row, clear the styling and set the display to inline.
  5. Next, grab all of the photoset photos.
  6. For each photo, set the image source to the desired size parameter.

Obviously, you can do whatever you want as far as styling goes in steps 4 and 6, but this was just a simple way to render all of the photoset photos at 75px and put them in a continuous line. If you have any questions, feel free to ask. I've tested it in my sandbox Tumblr and it does work.

ETA: I was not aware that {PhotoURL-250} worked inside of the photoset block, but it does. In that case, here is some simpler code:

{block:Photos}
<img src="{PhotoURL-250}" class="photoset-image" />
{/block:Photos}
<script type="text/javascript">
var photos = document.getElementsByClassName("photoset-image");
for(var i = 0; i < photos.length; i++)
{
    photos[i].style.width = '75px';
    var source = photos[i].src;
    var pos1 = source.lastIndexOf('_');
    var pos2 = source.lastIndexOf('.');
    photos[i].src = source.substring(0, pos1 + 1) + '75sq' + source.substring(pos2);
}
</script>

All this is doing is taking the URL provided and replacing it with the 75px square one.

Upvotes: 1

Related Questions