Skip to content

Instantly share code, notes, and snippets.

@peci1
Created May 22, 2014 21:02
Show Gist options
  • Save peci1/558a0d3b7ef27c5a9274 to your computer and use it in GitHub Desktop.
Save peci1/558a0d3b7ef27c5a9274 to your computer and use it in GitHub Desktop.
Silly (but powerful) .htaccess handling of script-generated web thumbnails
#############################
# START: THUMBNAIL HANDLING #
#############################
# Since handling thumbnails in Nette is painfully slow (loading the whole framework
# just to find out that the thumbnail has already existed), there is a workaround
# that finds all the generated thumbnails using mod_rewrite and only redirects to the
# script if generating a thumbnail is really needed.
# Even for generating thumbs the standard Nette usage is slow, so there is another workaround.
# The ThumbnailPresenter is not really a presenter. Its entry point isn't index.php, but
# document_root/thumbnail.php, which skips the most of the framework and then calls
# app/thumbnail.php. That file contains the thumbnail generating code. However, there is
# also app/DefaultModule/ThumbnailPresenter.php in which the signature of the default
# action has to be. And there is also needed a record in Nette router to be able to generate
# the thumbnail links.
# The basic idea of these rules is the following:
# 1. thumbnail/path/and/name.jpg/160/120/123456789/1
# 2. convert the url-parameter to only contain alphanumeric chars and -_ (and end with an extension like .jpg)
# thumbnail-webalizing/path_and_name.jpg/160/120/123456789
# 3. data/temp/preview-path_and_name-160x120-123456789.jpg.toolarge
# 4. If file from 3. exists, redirect either to the original image or the too-large-placeholder
# 5. Skip .toolarge from 3.
# 6. If the file exists, we've found the thumbnail, so serve it
# 7. Otherwise redirect to thumbnail.php to generate the thumbnail
# make sure the left part corresponds to the thumbnail router defined in APP_DIR/bootstrap-application.php
# the E=...:... flags mean setting environment variables which are accessible further in the script via %{ENV:VARNAME}
# the DPI flag means Discard PathInfo and is needed - if it missed, mod_rewrite would append the whole original URL to the rewritten one (WTF???)
RewriteRule ^thumbnail/(.*)/([0-9]+)/([0-9]+)/([0-9]+)/([01])/?$ thumbnail-webalizing/$1/$2/$3/$4 [E=ORIGURL:$1,E=FALLBACKTOLARGE:$5,DPI]
# translate all characters in the url-parameter other than a-zA-Z0-9_- to an underscore
# this is achieved via the N flag which tells "restart the rewriting from the first rule again (but restart with the current rewritten address)
# you can imagine this as a while loop substituting one character at a time
RewriteRule ^thumbnail-webalizing/([a-zA-Z0-9_-]*)[^a-zA-Z0-9_-](.*)\.(.{3,4})/([0-9]+)/([0-9]+)/([0-9]+)$ thumbnail-webalizing/$1_$2.$3/$4/$5/$6 [N,DPI]
# now we have the url-parameter in the correct form, so we can create the thumbnail filename
# and we right away append the .toolarge extension to first check if we don't have to send a substitute image
RewriteRule ^thumbnail-webalizing/(.*)\.(.{3,4})/([0-9]+)/([0-9]+)/([0-9]+)$ data/temp/preview-$1-$3x$4-$5.$2.toolarge [DPI]
# recalling the environment variable FALLBACKTOLARGE (set above) we decide whether to return the original image or a too-large-substitute image
# but only if the .toolarge file exists
RewriteCond %{ENV:FALLBACKTOLARGE} ^1$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^data/temp/preview-.*-[0-9]+x[0-9]+-[0-9]+\..{3,4}\.toolarge$ %{ENV:ORIGURL} [L]
RewriteCond %{ENV:FALLBACKTOLARGE} ^0$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^data/temp/preview-.*-[0-9]+x[0-9]+-[0-9]+\..{3,4}\.toolarge$ images/toolarge_placeholder.png [L]
# the .toolarge file doesn't exist, so we can move on an remove the .toolarge extension
RewriteRule ^(data/temp/preview-.*-[0-9]+x[0-9]+-[0-9]+\..{3,4})\.toolarge$ $1
# if the thumbnail file exists, return it
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(data/temp/preview-.*-[0-9]+x[0-9]+-[0-9]+\..{3,4})$ $1 [L]
# if the thumbnail file doesn't exist, call the creating script
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^data/temp/preview-.*-([0-9]+)x([0-9]+)-([0-9]+)\..{3,4}$ thumbnail.php?url=%{ENV:ORIGURL}&width=$1&height=$2&timestamp=$3&fallbackToLarge=%{ENV:FALLBACKTOLARGE} [L]
###########################
# END: THUMBNAIL HANDLING #
###########################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment