On this page, I talk about how to do images in your Web pages. Images involve macros, and I haven’t formally discussed macros yet, but you don’t actually need to understand the details of macros in order to do images, and users are naturally anxious to start using images right away; hence this independent discussion.
To generate references to images within the site, you do two things, as follows:
First, you have to have an image file. Place it in an #images
folder in your source folder, in a location such that it will be found when the page table is built. (Personally, I usually just keep all images in a single top-level #images
folder.)
Second, in the page body or template, use the imageref()
call in a macro. For example, you might say this:
<%= imageref("myimage") %>
If the image file’s simple name (without the extension) is myimage
(for instance, it might be myimage.png
), it will be located (in the #images
folder) and copied out into the Web site folder. The macro call then returns an <img>
tag whose src
attribute is a relative URL from the page being built to the image file. The <img>
tag will also have a height
, width
, and alt
attribute.
Every #images
folder containing an image file that is actually referred to by an imageref()
call results in a folder in the Web site at the same relative location, called images
, and the image file is copied into this folder. Thus you can have many images
folders throughout your site, though the simplest and most common situation is probably to have a single #images
folder at the top level of your source folder, where all pages can see it, and thus a single images
folder in the rendered site.
An optional second parameter in the imageref()
call is a hash of names and values that you can use to set additional attributes of the <img>
tag that will be generated. You may supply as many as you like of the following:
:height
, :width
. It is not usual to supply these; if you don’t, they will be supplied for you. RubyFrontier knows how to get the height and width of a jpeg
, gif
, png
, or tiff
by examination of the file. To suppress height and width attributes altogether, specify :nosize
.
:alt
. The alt
attribute. This is required by the XHTML standard, so if you don’t supply any value, RubyFrontier will include an alt
attribute for you, supplying a value of "image"
.
:name
, :id
, :hspace
, :vspace
, :align
, :style
, :class
, :title
, :border
. These are all standard <img>
attributes, and they work just as you would expect: if you supply one, RubyFrontier will use the value that you give as that value for that attribute in the <img>
tag.
:ismap
. The value doesn’t matter; true
is a good choice.
:rollsrc
. Use this as a simple way to get the image to toggle to a different image when the mouse is hovering over it (as in a “rollover button”). The value should be the simple name (with no extension) of the second image, which will be found in the #images
folder and written out to disk in the Web site folder. The <img>
tag will be given appropriate onmouseover
and onmouseout
attributes, using JavaScript to alter the displayed image. (Note: Good little JavaScripters will probably also want the page to include code to pre-cache the alternate image. RubyFrontier does not presently do this for you.)
So, for example, an imageref()
call that includes some of these optional values might look like this:
<%= imageref("myimage", {:border => "1", :alt => "A great image"}) %>
imageref()
All of the above presumes that you’re calling imageref()
to generate an <img>
tag. But there are circumstances where you want to refer to an image within your site, without using an <img>
tag. For example, you might do this from a JavaScript or CSS file.
In this case, you’re going to need to use some other strategy to get the image copied from the source folder into the Web site folder. There are two main strategies:
Put such images in a folder (within the source folder) that isn’t a directive. For example, the folder might be called otherimages
. In accordance with the rules, RubyFrontier will copy the folder into the Web site, and since the images are not page objects, it will copy the images as well. You must then adjust any referencing URLs so that they refer to the images in the correct relative location. The disadvantage of this approach is that the copying only happens when you publish the entire site. But it has the advantage of extreme simplicity.
Keep the images in the #images
folder, and call html.getImageData()
in a macro explicitly for each image you want copied out to the Web site. The method html.getImageData()
is a utility called by imageref()
. It takes the same kind of string reference that imageref()
does; it fetches a bunch of data about the image (such as its dimensions), but it has the side effect of causing the image to be copied out. The advantage of this is that you can make it happen as you render any page.
To help with this, starting in RubyFrontier 0.9.9.6, JavaScript and CSS files are now macro-processed by the standard macros that deal with them. This not full macro-processing; it’s really just a call to ERB in the current context. But the current context is the PageMaker object, so calling getImageData()
without the .html
prefix will work. Moreover, in the case of a stylesheet or JavaScript file that’s going to be linked to (not embedded), adrPageTable[:sheetLoc]
will be the path to that file, so this can be used to work out the relative URL to the image.
For example, here’s how a CSS stylesheet file might refer to a background image:
<% def writeAndGetRelativeURI(im)
getImageData(im)[:path].relative_uri_from(adrPageTable[:sheetLoc])
end %>
body {
background-image: url(<%= writeAndGetRelativeURI("body_bg") %>);
background-repeat: repeat;
}
The method writeAndGetRelativeURI()
does just what it says: it causes the named image to be written into the Web site, and works out its URL relative to the stylesheet itself within the Web site. That relative URL is substituted within the CSS, in the url(...)
construct, and thus the relative URL works — it is correct, and the image is present. Meanwhile, the def
stuff at the top of the stylesheet is removed (note the lack of an equal-sign in the macro call; this means that nothing is substituted into the stylesheet at this point), and so the stylesheet is legal.
Nevertheless, in some cases (where, for example, there are a lot of images), you might like to take a simpler batch approach and copy out explicitly all the images in the #images
folder every time any page is rendered, by calling a macro (let’s call it spit()
) in the template:
def spit
h = @adrPageTable["images"]
h.keys.each do |img|
html.getImageData(img)
end
end
This is not particularly inefficient, because html.getImageData()
only performs an actual copy if an actual copy needs to be performed; if the image has already been copied into place in the Web site, and has the same modification date as the original, no copying takes place. The spit
macro ignores the data returned by html.getImageData
, and your call to spit()
would also ignore its results, like this:
<% spit() %>
(Note the lack of an equal-sign in the macro call; this means that no results are entered into the Web page being rendered at this point.) It is possible to use html.getImageData
in more sophisticated ways, where you actually do care about the results it returns; for an example, look at the caption()
macro used to generate the image-plus-caption pairs in this documentation.
This documentation prepared
by Matt Neuburg, phd = matt at tidbits dot com
(http://www.apeth.net/matt/),
using RubyFrontier.
Download RubyFrontier from
GitHub.