Eksempler
>Bildegalleri
Bildegalleri
Vi skal lage løsningen på følgende måte:
- Vi lager en XML-fil som inneholder en kopling mellom bildenavn, dato når bildet er tatt(hvis det er et fotografi) og en kort beskrivelse, data.xml
- Vi lager en master for en framvisningsside, master.html
- Vi lager en Pythonmodul, makegalleri.py, som leser data.xml, master.html og produserer index.html som er den siden som skal vise fram galleriet.
- Vi skriver en javascript-fil, galleri.js, som inkluderes i index.html og tar seg av dynamikken på framvisningssiden,
- Vi skriver css-fil, galleri.css, som justerer layouten for oss.
Datafil
<?xml version="1.0" encoding="utf-8"?>
<bilder>
<front>
<![CDATA[
<h1>Noen bilder</h1>
<p>Her finner du litt diverse bilder
</p>
]]>
</front>
<bilde>
<imagename>bilde1</imagename>
<dato>2007-03-30</dato>
<text>Pussig fyr</text>
</bilde>
...
</bilder>
Master for indexfil
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<link href="galleri.css" rel="STYLESHEET" />
<title>Noen bilder</title>
<script type="text/javascript" src="galleri.js"> </script>
</head>
<body onload="init()">
<!-- navigator -->
<div class="printhide" style="position:absolute;left:17px;top:7px">
<span class="mybutton" onclick="previous()"><</span>
<span class="mybutton" id="autobutton" onclick="toggle()">>></span>
<span class="mybutton" onclick="next()">></span>
</div>
<div style="float:left">
<div <!-- STYLE FROM PYCODE --> id="hilitedimg">
</div>
</div>
<div id="content" class="printhide">
<!-- CONTENT FROM PYCODE -->
</div>
<div style="clear:left;text-align:center">
<hr/>
<p>
En enkel demonstrasjon.
Skaler vinduet så ser du at
de små bildene flyter.
Avspillingskontrollen burde kanskje flyttes ?
</p>
<p>
<a href="javascript:history.back()">Tilbake</a>
</p>
</div>
</body>
</html>
Vi har satt inn to kommentarer som skal erstattes med materiale som produseres i Pythonmodulen.
Pythonmodul
Merk at modulen bruker Python Imaging Library (PIL) til å skalere ned bildet til en akseptabel størrelse og til å lage thumbnails.
import xml.dom.minidom
import Image
import os
"""
See: http://www.ia.hiof.no/~borres/ml/galleri/p-galleri.html
"""
thumbFragment="""
<span>
<a href="javascript:hilite('%s')" title="Vis dette">
<img alt="?" src="images/%s" />
</a>
<div style="display:none" id="thumb%s">
<div><img src="images/%s.jpg" alt="-"/></div>
<div ><!-- datoen -->
%s
</div>
<div><!-- teksten -->
%s
</div>
</div>
</span>
"""
#------------------------
# Read / write text files
def getTextFile(filename):
try:
file=open(filename,'r')
res=file.read()
file.close()
return res
except:
print 'Trouble reading: '+filename
return None
def storeTextFile(filename,txt):
try:
file=open(filename,'w')
file.write(txt)
file.close()
except:
print 'Trouble writing to: '+filename
#----------------------------------------------
# extract text from a node
def getText(nodelist):
rc = ''
for node in nodelist:
if node.nodeType == node.TEXT_NODE or \
node.nodeType == node.CDATA_SECTION_NODE:
t=node.data.encode('ISO-8859-1')
rc += t
return rc
#----------------------------------------------
# produce a thumbnail
def makeThumb(infile,outfile):
global maxWidth
global maxHeight
im = Image.open(infile)
w=im.size[0]
if w > maxWidth:
maxWidth=w
h=im.size[1]
if h > maxHeight:
maxHeight=h
tsize=T_SIZE,T_SIZE
if w > h:
tsize= int(round(1.0*w/h*T_SIZE)),int(round(1.0*w/h*T_SIZE))
im.thumbnail(tsize,Image.ANTIALIAS)
im.save(outfile,"JPEG")
#-----------------------------------------------
# resize an image, down to max height and width
def resizeImage(imfile,maxW,maxH):
im = Image.open(imfile)
w=im.size[0]
h=im.size[1]
if w <= maxW and h <= maxH:
return
if w > maxW:
h=int(round((1.0*h/w)*maxW))
w=maxW
if h > maxH:
w=int(round((1.0*w/h)*maxH))
h=maxH
isize=w,h
im=im.resize(isize,Image.ANTIALIAS)
im.save(imfile,"JPEG")
#----------------------------------------------
# build DOM tree from XML-file
def buildDom(filename):
T=getTextFile(filename)
if T== None:
return None
try:
return xml.dom.minidom.parseString(T)
except:
print 'Error building dom '
return None
#----------------------------------------------
# Find all image elements and populate
# a spanFragment list
def buildPage(dom,catalog):
global masterPage
res=''
# pick up frontpage
front=''
try:
front=getText(dom.getElementsByTagName('front')[0].childNodes)
except:
front='<p>Bilder</p>'
res="""
<div style="display:none" id="thumb0">
%s
</div>
"""%front
# pick up imagedescriptions
bildeliste=dom.getElementsByTagName('bilde')
ix=0
for bilde in bildeliste:
ix+=1
# pick up imagename (106_0629), dato(2006-04-14)
# and txt(dette er en tekst)
try:
imx=bilde.getElementsByTagName('imagename')[0]
imagename=getText(imx.childNodes)
if imagename.endswith('.jpg'):
imagename=imagename.replace('.jpg','')
dato=getText(bilde.getElementsByTagName('dato')[0].childNodes)
txt=getText(bilde.getElementsByTagName('text')[0].childNodes)
imagefile=catalog+'images\\'+imagename+'.jpg'
thumbfile=catalog+'images\\t_'+imagename+'.jpg'
resizeImage(imagefile,I_WIDTH,I_HEIGTH)
makeThumb(imagefile,thumbfile)
res+='\n'+thumbFragment%\
(str(ix),'t_'+imagename+'.jpg',str(ix),imagename,dato,txt)
except:
print 'something went wrong,bilde nr: '+str(ix)
style='style="text-align:center;width:%spx;height:%spx"'%\
(str(maxWidth+5),str(maxHeight+40))
masterPage=masterPage.replace('<!-- STYLE FROM PYCODE -->',style)
masterPage=masterPage.replace('<!-- CONTENT FROM PYCODE -->',res)
return masterPage
#-------------
catalog='f:\\html\\ml\\galleri\\'
#---------------------------------------------
# max size for images to show
I_WIDTH=700
I_HEIGTH=500
# will be set as max image dimensions found
maxWidth=20
maxHeight=20
# max heigth for thumbnail
T_SIZE=50
masterPage=getTextFile(catalog+'master.html')
if masterPage==None:
exit(0)
dom=buildDom(catalog+'data.xml')
if dom != None:
res=buildPage(dom,catalog)
try:
outfile=open(catalog+'index.html','w')
outfile.write(res)
outfile.close()
except:
print 'Error writing file ',filename
Javascript
var currentNr=0;
var maxNr=1;
var stopped=true;
function init()
{
var nr=0;
while (document.getElementById('thumb'+nr))
nr+=1
maxNr=nr-1;
hilite('0');
}
function hilite(nr)
{
var content=document.getElementById('thumb'+nr).innerHTML;
document.getElementById('hilitedimg').innerHTML=
'<div>'+content+'</div>';
currentNr=parseInt(nr);
}
function previous()
{
if(currentNr==0)
hilite(maxNr);
else
hilite(currentNr-1);
}
function next()
{
if(currentNr==maxNr)
hilite(0);
else
hilite(currentNr+1);
}
function toggle()
{
if(stopped)
{
stopped=false;
setTimeout("show()",3000);
document.getElementById('autobutton').innerHTML=
' || ';
}
else
{
stopped=true;
document.getElementById('autobutton').innerHTML=
' >> ';
}
}
function show()
{
if (!stopped)
{
next();
setTimeout("show()",3000);
}
}
Stilsett
@media screen
{
body{
color: black;
font-family:"Verdana","Geneva","Arial","Times",sans-serif;
font-size:13px;
margin:5px;
padding:0px;
}
.text{font-size:14px}
.dato{color:gray}
.mybutton{cursor:pointer;color:black;
background-color:#EED9B0;
border-style:solid;
border-width:thin;
padding:5px;
font-weight:bold;
margin-right:2px}
h2{background-color:#EED9B0;}
}
@media print
{
.printhide{display:none;font-size:16px;text-align:center}
}