Link to home
Start Free TrialLog in
Avatar of RollinNow
RollinNow

asked on

Random image swap every 60 seconds

Currently at every load of a page, I run banner.cfm which cfincludes the following code and displays a different image:

<td height="100" rowspan="2">
  <cfinclude template="b/banner.cfm">
</td>


<!--- banner.cfm --->
<div style='width:500px; height:100px; background-image:url(
   <cfparam name="imageswap" default="#randrange(1,3)#">
   <cfif
                    imageswap is "1"><img src="image1.jpg">
       <cfelseif imageswap is "2"><img src="image2.jpg">
       <cfelseif imageswap is "2"><img src="image3.jpg">
</cfif>
)'></div>

There are nearly 100 images so I made my example short. It's crude but it works okay, as it is. But I'd rather make the random effect less random by displaying the same image on any page load for at least one minute, for everyone who hits the website, then load another. This way I also avoid excessive hits to the system, and the same image is already loaded into the client browser. Perhaps some kind of session id associated with banner.cfm? So, what would I have to modify with my code to get this idea working?

I'm also wondering if running through 100 cfelseif may be a problem. SQL and CF both have cache set, so perhaps not, but I'm wondering about this too. Maybe there's a much more efficient way to do this...?

    - Georgia
Avatar of aseusainc
aseusainc

Easy way to do this is with a scheduled event from cfadmin.  In the event, you will generate the code for the banner and save it out...

So basically, you would have

Event.cfm:

<cfhttp url="whateveryourpathis/bannerbuilder.cfm"
           method="GET"
           resolveurl="True"
           file="banner.cfm"
           path="pathtowhereyouwantbanner.cfm"
           throwonerror="Yes">


Bannerbuilder.cfm:

<div style='width:500px; height:100px; background-image:url(
   <img src="image#randrange(1,100)#.jpg">
)'></div>

Then just cfinclude banner.cfm wherever you need it.

So the wrapup...You have an event that you run every x minutes.  This calls event.cfm.  Event.cfm will call a page that randomizes the banner, then saves it as banner.cfm.  Then you just include the banner.cfm.  VERY low overhead this way, and also the right way to do the image without 100 cfif's.
Avatar of RollinNow

ASKER

Hi there, again, Aseusainc,

Hmm, looks interesting. Yes, we do run scheduled events now. I'll give this a try but first, one concept I'm not quite getting:

For the image you have:

<img src="image#randrange(1,100)#.jpg">

How does that line know which images to use? Do I repeat that line for each image like this:

<img src="image#randrange(1,100)#image1.jpg">
<img src="image#randrange(1,100)#image2.jpg">
<img src="image#randrange(1,100)#image3.jpg">

And actually, the images are not named like that but use unique names. All images are stored in the same directory, if that helps. I could rename them in sequence but would rather not.

Please clarify this a bit for my amateur brain and I'll give it my best college try.

  - Georgia
This will just pick a random image...like image1.jpg, image55.jpg.

There are a ton of freeware file renamers on the net that would make renaming them easy.  You're other choice would be to toss them in a database and keep an index column.

Sorry I haven't been around EE much.  Just went through a merger at work, not happy, job hunting, internet usage now monitored, etc etc.  <SIGH>
> This will just pick a random image
Pick from where?

And which set of images? Does this sort through and pick any image from the same directory where banner.cfm is run, or something else? I know it must be clear to you, but unfortunately, it's still not at all clear to me.  Remember, this is a background image so my first example was misleading. All I need is the name, not the image tag. It should be:

Are you suggesting I replace my code here:

<div style='width:500px; height:100px; background-image:url(
<cfparam name="imageswap" default="#randrange(1, 97)#">
<cfif     imageswap is "1">"/files/b/the_aviator.jpg"
<cfelseif imageswap is "2">"/files/b/constant_gardener.jpg"
)'></div>

with your one line:

<img src="image#randrange(1,100)#.jpg

No matter what I try, I can't get that to display and background image.

What do I replace in my code above and what would I end with with or replace?

I also don't understand if my images need to be renamed so they can be used with your suggestion.  And I don't know if I need to include the image path and if so, how and where. The images are in the same directory as banner.cfm. I can do whatever is required, but I need to understand the requirements, first.

Would you please show me how your suggestion would work so I can then understand what you mean, and how to do it?

Or anyone else who would like to share the points to help make it clear for me.

Thanks,

  -  Georgia


Looking at this again, I looks like you're suggesting I rename all the images to some root name such as:

"image"

Dah! Click.

And that will display the random range of the root "image", and pick the rest of the filename? That must be it.

"image#randrange(1,100)#.jpg"

Hmm. It wouldn't take too long to rename them, but it would be very difficult to maintain. I really need the filenames for reference. I could make another reference beside them, or in a database, but then, I'm making this more complicated than I had hoped.

But my other questions about the path or still important.

 - Georgia


Sorry, me again.

I experimented a bit and answered my own confusion. If that makes sense. I just added the path like this:

<div style="width:500px; height:100px; background-image:url(/files/b/sequenced/banner_#randrange(1,100)#.jpg)"></div>


However, I will be adding more images, up to 1000. How best to name the images? Seems like 001, 002 will not work as the randrange looks for 1, or 01.

I can use url(/files/b/sequenced/banner_#randrange(1,100)# but that still looks for 01 which now does not exist. It goes against all my experience to name the images 1,2,3, all the way up to 999 because DOS did not handle them well.

Any final thoughts, anyone, before I close this and give the points?

  - Georgia



ASKER CERTIFIED SOLUTION
Avatar of aseusainc
aseusainc

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Needless to say, you can change the filter in the cfdirectory tag to do jpgs (it will probably even accept multiple type IE: "*.gif,*.jpg"), as well as combine some of the cfset stuff.  I like to break it out into a bunch of steps, as it makes it easier to follow, and helps others to learn.
I'll try to work test that soon, keep me busy with ideas. I already implimented your other idea and it seems to be working just fine. Time to close this question now.

By the way, any drawbacks using CFDIRECTORY compared with other methods we've discussed? This is a busy system, but for this case, only one image per page is being displayed.

So, thanks for the great and ideas.

  - Georgia


No real drawback in the manner in which you'll be using it.  If you tie this all to an event every minute or two, then regardless of traffic, you wont be hitting this for each visitor, you'll just be cfincluding a static include that gets updated by the event when it fires.
Avatar of gdemaria

 Georgia,

 Another suggestion on efficiency is using the application scope for this.   Store in the application scope the list of files, it will be shared by all users.  You only need to re-read the directory every X hours (whever you have the application set to expire in <cfapplication applicationTimeout="">.   Otherwise, it will just keep pulling a random image.

<cfif NOT IsDefined('application.listOfFiles')>  <!---- only run this once in a while ---->
  <CFDIRECTORY ACTION="list"
      DIRECTORY="c:\Inetpub\wwwroot\ColdFusion\images"
      NAME="filenamelist"
      FILTER="*.gif">
  <cfset application.listoffiles = #ValueList(filenamelist.name)#>
</cfif>

<cfset variables.numberoffiles = listlen(application.listoffiles)>
<cfset variables.theimage = listgetat('#listoffiles#',RandRange(1, variables.numberoffiles))>

<cfoutput>#variables.theimage#</cfoutput>



 There is a catch to this:  the list of images will not be updated immediately, only every X minutes or hours (depending on the timeout set in applicationtimeout).   If you don't mind putting a new image up there and having it not be part of the mix for a little while.  This will work well.


 ...and of course, always scope your variables :)