sexverhalen

Gratis sexverhalen - Eroverhalen.com

iedere dag weer nieuwe geile sexverhalen

Nieuwe Sexverhalen

stuur ons uw zelfgeschreven sexverhaal stuur uw verhaal in

Een nieuwe verleiding.
We keken op de paaltjes naast hun, verbaasd keken we, "het zijn onze
buren"! Zij liepen heupwiegend verder en stoorde niet aan ons, ik zette
de auto neer en zette de tent op. Na alles te hebben uitgepakt wilde
Brid wel eens douchen, ze plakte overal zoals ze zij. Ze wilde een
koffer pakken, maar bleef versteld staan. "onze kleren staan nog thuis,
het enige wat ik hier heb is nog een jurkje, een bikini en een zwembroek
van jou en wat we nog aan hebben". Ik stelde haar gerust, "we gaan hier
wel wat kleren kopen en als alles goed gaat heb je slechts je badkleding
nodig". Ze liep richting douches, ik volgde haar stevige billen in dat
krappe hot pants, de billen vielen wellustig naar buiten. Nog geen half
uurtje kwam ze terug, het jurkje bedekte net aan haar bikinislip, het
was enorm geil, ze ging naast me zitten, nu ging ik me douchen. Toen ik
terug kwam zat mijn meisje met de buren te babbelen, ze kwamen uit
Duistland. Hij heette Günther en zij heette Steffie, hij was net als ik
gebouwd maar had wat haar op zijn borst en een stel kloten in het
broekje, zij was iets kleiner, stevige borsten, net iets kleiner dan van
Brid een tatoeage vanuit haar bikinistring van een draakje en een stel
geile benen, haar bikinilijn was goed verzorgd ik kon geen schaamhaartje
ontdekken hoe ze er bij zat.

Brid had verteld dat wij geen kleding bij ons hadden en van hen konden
we wel wat lenen en Günther wist nog wel een marktje waar je enorme
mooie kleding voor een habbekrats kon kopen. Het was al vrij snel laat
geworden en we besloten maar eens te gaan eten, na het eten besloten we
maar onder het wol te gaan. In de tent kleedde Brid zich geheel uit en
ik kon niet achter blijven, wij slapen graag naakt, van haar lichaam
kreeg ik een enorme erectie, maar zij hield me van haar af, morgen
dubbel beloofde ze.

Het was inmiddels half een en naast ons hoorde we mensen zachtjes
kreunen en zuchten, stiekem keek ik naar buiten, het geluid kwam bij
onze buren vandaan, door schimmenspel van de lamp achter hun tent zag ik
hoe hij haar vanachter nam, zachtjes trok ik aan mijn lat, tot Brid me
stoorde. "Laat ze lekker, en je mag gerust trekken maar je goedje bewaar
je" en gaf een kus op de paarse eikel, ik stopte.

De volgende morgen hing bij onze tent wat kleding van de buurtjes, ik
een short met shirt en Brid een minirokje en een haltertje, wat
duidelijk iets te krap zat, haar borsten priemden er dwars door heen,
nadat we hadden gedoucht waren de heerlijke mensen naast ons wakker, na
wat vriendelijke woorden ging zij ook douchen, ik bekeek Steffie hoe
kontje bewoog in het jurkje. Brid stootte me wakker, "lekker hé, zo'n
vrouwtje"?

"Daar zeg ik geen nee tegen als ik haar mag naaien", Brid gaf me een por
"en ik hem", we lachte. Niet veel later kwamen ze terug en vroeg of Brid
met haar mee wilde gaan om te kijken op de markt. Al te graag wilde ze
en stapte bij Steffie in de wagen. Günther en ik bleven achter, we
gingen naar het Balaton meer. Beetje zwemmen en de vrouwtjes bekijken,
ik merkte dat we beide bijna de zelfde smaak hadden en vroeg hem over
gisteren, hij lachte. Na een lange tijd kwamen er twee dames op ons af,
onze vrouwen. Wauw wat zagen zij er enorm uit. Steffie weer in dat geile
gele bikini en Brid had er ook een aan een witte, nadat zij narderde kon
je bijna haar piercing in haar string zien, ze zag eruit om terplekke te
neuken, haar heupketting en enkelketting en navelpiercing glommen tegen
je op, ze kwamen naast ons zitten en gaven ons een hete lange tongzoen.
Brid ging naast me liggen en Steffie ging met Günther het water in. "Wat
een geile meid zeg, ze kikt op mijn navelpiercing en toen ik vertelde
dat ik er nog twee had liep ze bijna leeg, ook vertelde ik haar dat jij
er een heb, ze zou hem zo graag willen zien, maar liever voelen". "Wat
in haar doosje" vroeg ik. "Misschien ook wel, als we zo doorgaan word
het nog een partnerruil". "Geil".

Het stelletje kwam weer terug, zo te zien had ze ook alles verteld, hij
glunderde. Op het gras lagen we en wisselde wat uit, ik haalde voor ons
vier biertjes en bij terug komst lag hij tussen beide vrouwen. "Hoe vind
je mijn nieuwe aanwinst" vroeg hij in het Duits. "Kom naast me" vroeg
Steffie en tikte op de grond. Het bier stroomde rijkelijk en we werden
losser, de zon maakte ons ook aardig geil, tot we besloten terug te
gaan, opmaken en eten. Brid had aardig kleding gekocht ook voor mij
enkele stringtanga's. Na het douchen wachtte ik op haar, daar kwam ze
haar zwarte haar in een knot, een lichte dunne kort jurkje, haar borsten
zaten krap in een zwarte bh en ze droeg duidelijk te zien een zwarte
string, ze provoceerde gewoon. Samen liepen we terug maar in de tent had
ik stevig vast en gewillig liet ze maar kutje voelen, nat niet van water
maar duidelijk geil, de schaamlipjes dik, mijn paal haalde ze eruit.
"Snel neem me, laat me je voelen" en ik drukte mijn lat tussen haar
lippen, ze klom tegen me op en een gil van extase liet ze horen, een
schot van mij vulde haar doosje het stroomde er zelfs uit. Brid veegde
het af met een zakdoekje en deed alles weer "normaal". "Zo en nu de
tweede gang".

Steffie en Günther zaten al op ons te wachten en schoof Brid een stoel
onder haar natte kont. Ik complenteerde Steffie met haar mooie dunne
zwarte korte jurkje, wat me deed denken aan een onderjurk, het stond
haar geil. Tijdens het eten maakte we geile opmerkingen naar elkaar en
stiekem voelde ik hoe Steffie's hand over mijn kruis ging, ze was enorm
geil. Na het eten wat lekker was namen we enkele biertjes met snaps, we
werden tipsy en de tijd vloog. Terug in de tent kreeg ik mijn lat niet
meer omhoog dus toch teleurstellend voor Brid. De volgende dag heb ik
haar 's morgens verwend met een heerlijke befbeurt, ik likte haar
volledig uit en liet haar twee maal klaar komen, voordat ik in haar
bewoog. Een derde keer begon zich te melden en rillend kwam ze klaar,
vlug bewoog ze onder me uit en nam mijn dikke paal tussen de warme
lippen, krachtig zoog ze en tegen haar gehemelte spoot ik me leeg,
likkend en spinnend lag ze na te genieten alvorens we gingen douchen. De
hele dag verbleven we op strand, ons huid kleurde goed bij, Brid had
haar borsten inmiddels ook laten bijkleuren, dit ging dagen zo door.
Samen met hen op het strand, eten en 's nachts of 's ochtends een fikse
neukbeurt.

Een volgende dag besloten we het land te bekijken en reden met Steffie
en Günther mee, ik voor en de dames achter, voor deze gelegenheid hadden
ze zich luchtig gekleed een wijde korte jurkje maar boven strak door
spaghetti bandjes. Günther reed door dorpjes en langs wegen waar bijna
niemand kwam, door de bossen en bij een mooi kaal plekje stopte hij,
"dit is een heel mooi plekje, mooi uitzicht over het meer", we stapten
uit en Steffie gooide een kleed op de grond een mandje met eten zette ze
erbij.

Het was zeker mooi en de zon brandde fel, je kreeg het er heet van. We
gingen op het kleed zitten, de vrouwen iets ongemakkelijk door hun
jurkjes, die niets meer bedekte van hun string. Mijn broek werd al snel
te klein en van Günther ook, de dames hadden het gezien en trokken hun
jurkjes uit, Steffie deed als eerste haar string doen vallen een kalle
doosje had ze, een tatoeage als draak dat uit haar schaamstreek naar
haar navel deed bewegen, brid kon niet achter blijven, haar piercing
glom tussen de dikke paarse schaamlippen, een streepje haar had zij.
Günther had al vlug zijn kleding uit en pakte zijn meisje beet, zijn
stevie lange dikke paal staand. Ik liep achter Brid aan, mijn lat stond
ook overeind, de ring in de eikel glom in de zon. Brid ging op haar
knieën en nam hem tussen de lippen, diep zoog ze hem naar binnen, ik
trok haar hoofd naar mij toe alsof ik haar neukte. Naast ons waren de
andere twee bezig, standje 69. Haar benen klemden zijn hoofd en ze gilde
en gaf me een knipoog. "zullen we ruilen" vroeg ze. Brid voelde wel wat
voor zo'n dikke stevige lat en ik wilde maar al te graag haar neuken en
wij wisselden van partner. Steffie's mondje was heet en vochtig toen ze
me begon te pijpen, haar tong speelde met de ring door mijn eikel,
geheel zoog ze in haar keeltje ik masseerde haar stevige kleinere
borsten. Brid werd uitvoerig gelikt, ze spinde van genot. Nu wilde ik
haar kutje likken en we draaide ons om, ze smaakte anders lekker en
geil, ze was natter en ik likte haar nectar uit haar pruimpje, schokkend
voelde ik haar orgasme komen meer en meer geil liet ze vloeien, gillend
en kreunend kwam ze, ze rilde helemaal. Naast ons waren ze stevig aan
het neuken, zijn kloten sloegen tegen Brid's kontje. Steffie ging
uitgebreid voor me zitten op haar knietjes, haar vruchtje hield ze met
beide handen open, zonder enig weerstand dreef ik in haar, door het
stelletje naast ons dat klaar kwam, kwamen wij ook al vlug, het geil
droop uit beide kutjes, ze poetsten en smeerde het over hun lichaam uit,
de zon deed de rest. Lang zijn we gebleven tot de zon onder ging en toen
terug reden, naar dat plekje zijn we nog driemaal geweest. Jammer voor
de buurtjes hun vakantie was bijna ten einde, over enkele dagen zouden
ze terug gaan. Het was al die dagen heet en geil aan toe gegaan. Brid
vond het jammer en ik ook, tot Günther op het idee kwam om even te
bellen of hij nog wat langer kon verblijven, jammer dat kon niet, maar
een oplossing had hij, als wij Steffie terug zouden brengen op de terug
reis dan kon zij nog enkele dagen bij ons verblijven, mits wij geen
probleem hadden, nou graag dachten we en zo ook Steffie. De laatste dag
zijn we allen nog eenmaal naar boven gereden, de meisjes waren nu
"degelijk" gekleed strakke stretch jurkjes met eronder duidelijk hun
zwarte bh en string. Boven op het kleed ging Brid nadat ze zich had
ontdaan van haar jurkje liggen, Steffie deed ook haar jurkje uit en
knielde voor haar neer, erotisch likte ze Brid, trok lustig haar bh uit
en toen die van haar, de tongen likte elkaar, strelend elkaars
lichamen. Voor het eerst was ik getuigen van Brid's wens om met een
vrouw te vrijen. Nu werd haar string uit gedaan en Steffie's. Ze likte
haar navel, zoog aan de ring en daalde af, likkend naar het
vrouwelijkste. Brid genoot, haar buikje bewoog heftiger en heftiger, ze
opende haar benen en liet zich door Steffie beffen, haar handen drukte
de blonde haren stevig in haar schoot, een kreun een zucht, ze had een
orgasme. Ze rolde Steffie opzij, nu zagen we hoe zij werd gebeft.
Günther en ik stonden naakt met onze palen in de hand, trekkend en
kijken naar het schouwspel. Steffie kwam al heel snel. Kruipend kwamen
ze op Günther af, ze likten beide aan zijn paal. "Dit is om je te
bedanken en ik kwam nog" beloofde ze. Brid ging voorover staan en liet
gewillig zijn paal tussen haar schaamlippen steken, Steffie likte hen
beide, je hoorde hoe nat ze was, een kreun en een brul, Brid's kutje was
gevuld met verse geil, met het terug trekken trok hij slierten mee, die
werden opgevangen door Steffie's rappe tong die ook Brid's kutje
schoonlikte. Door deze schouwspel spoot ik op de grond. Die avond waren
we flink doorgezakt en de volgende morgen hielpen we mee alles op te
ruimen en Steffie's bed bij ons in de tent te plaatsen, na enkele stevig
zoenen namen we afscheid.

Treurig was Steffie wel toen hij ons verliet maar Brid krikte haar
meteen op, aan het strand lagen we, en s'nachts had ik twee vrouwen die
ik moest bewerken. Voor ons waren deze dagen veel te snel om gegaan. Op
de terug reis zaten beide dames achter in, flink te elkaar gek te maken,
tot Steffie mij een stukje stof onder de neus schoof en hem in de mond
propte, ik rook en proefde geil maar van wie, ik vroeg het haar. Ze klom
vanachter tussen de voorstoelen naar voren, ( gemakkelijk als je een
grote ruimte wagen heb ) onder haar lambadarokje zag ik een streepje
stof, dus het was van mijn vrouwtje.

Steffie draaide de spiegel zo dat ik naar achteren keek, daar lag Brid
met het rokje omhoog en de benen wijd, te spelen met haar lipjes. Mijn
paal groeide en groeide, tot hij bevrijd werd door Steffie, haar hoofd
ging naar beneden en tijdens het rijden pijpten ze me, enkele bussen met
mensen reden me nog voorbij, snelheid maakte ik niet echt alleen in mijn
kruis borrelde ik en waarschuwde dat ik zo zou spuiten. Achter in de
spiegel zag ik Brid flink aan het vingeren en riep naar Steffie dat ze
ook wat wilde. Te laat een explosie gevolgd door een slingering van de
auto vulde ik haar mondje met verse geilsappen, ze lispelde nog maar
bleef zuigen, ik verslapte, mijn merg zoog ze al het ware mee, voldaan

met volle mond kroop ze terug, wat ik nu zag gaf me bijna nog een
orgasme. Brid opende haar mond en steffie liet wat geil uit haar mondje
stromen, gevolgd door een lange tong zoen, je zag hoe zij genoten, Snel
reed ik van de weg een raststette op, gelukkig niemand, stopte en deed
de portier open, Steffie lag voor me op haar knieën, Brid te beffen,
langs het broekje stak ik mijn paal in en reed ons drieen naar een
enorme geile explosie, op de bank zie je nog onze pretvlekken. Voldaan
en tijdelijk genezen reden we verder richting Wurzburg en brachten
Steffie heelhuids thuis, daar moesten we nog een nachtje blijven waar
het al te heet aan toe ging en met pijn in de kutstreek en kloten reden
we naar huis.

Nu houden we nog steeds contact via internet en wisselen elkaar foto's
uit, we hebben al besloten om volgend jaar naar Spanje te gaan.
Dit sexverhaal is geplaatst op 23 Apr 2010 door eroverhalen
Content Management Powered by CuteNews

parse( // aanroep om "dailer.template.htm" te parsen # array( # "link" => $templateLink, // in het template bestand word "%[link]% vervangen door de waarde in $templateLink # ) # ); # ###### # Door: Willem de Vries # Date: 9 februari 2005 # Voor: Virtual Pc Services # Versie: 2.2 # ###### # Changelog: # 1.0 (WdV 7-11-2003): statische functie ombouwen naar object # 1.1 (WdV 13-2-2004): parsen moet ook zonder parameters kunnen # 1.2 (JF 15-2-2004): Set functie toegevoegd om variablen aan template toe te voegen, aaroep: set(variablenaam, value) # 1.3 (JF 24-3-2004): Endless loop bug gefixed, bij openen van template kwam hij bij lege file of file zonder # regeleinde niet bij eof bij lezen van filesize. # 1.4 (WdV 04-3-2005): Nieuwe functie om default-waardes uit een HTML-comment veld te halen. # 2.0 (WdV 09-2-2005): grotendeels herschreven refresh() en parse() routine. Nu 50% sneller! # 2.1 (WdV 15-2-2005): Mogelijkheid om een template aan te maken vanuit een string ipv. een file uit te lezen # 2.2 (WdV 28-10-2005): On-the-fly compressie om geheugen te sparen, kleinere array properties # 2.3 (WdV 15-12-2005): Gebruik van de "TEMPLATE_SEARCH" superglobal om een (relatief) zoekpad op te geven waarin # templates gezocht moeten worden. ############################################################### function _slashjoin() { $out = array(); foreach(func_get_args() as $param) { if ($param) $out[] = $param; } return preg_replace('#([/]+)#', '/', join('/', $out)); } function _dirlist($str, $regex = '.*') { $out = array(); $dh = (is_dir($str)) ? @opendir($str) : null; while ($dh and $fil = readdir($dh)) { $out[] = _slashjoin($str, $fil); } if ( !$out) return; list($item) = array_values(preg_grep("|$regex|i", $out)); # error_log(__FUNCTION__ . " Matching items for |$regex|"); # error_log(__FUNCTION__ . " Subdirs in $str: " . join('|', $out)); # error_log(__FUNCTION__ . " Found dir '$item'"); return ($item) ? $item : $str; } class Template { var $fn = null; var $filename = null; var $ch = null; var $error = null; var $searchpath = null; var $searchdir = null; var $inf = null; var $def = null; var $me = 'object'; var $vars = array(); function Template($name) { # Compatibility $this->filename =& $this->fn; $this->me = strtoupper(get_class($this)); $this->searchpath = $GLOBALS[$this->me . "_SEARCH"]; if (defined($this->me . "_COMPRESS")) { foreach(array(array('gzcompress', 'gzuncompress'), array('gzdeflate', 'gzinflate')) as $grp) { if (function_exists($grp[0])) { $this->def = $grp[0]; $this->inf = $grp[1]; break; } } } $this->fn = $name; $this->refresh(); } function set($varname, $value = ''){ $this->vars[$varname] = $value; } function get($varname) { return $this->vars[$varname]; } function refresh() { if (!preg_match('/\.([^\.\/\s]+)$/', $this->fn, $found) ) { $this->cached($this->fn); $this->fn = null; $this->error = null; return; } # Implementatie zoekpad $subdirs = preg_split('/([\s]*;[\s]*)/', $this->searchpath); if (! $subdirs) $subdirs = array(''); list($a, $up, $b, $path) = preg_match('/^(([\.]+\/)*)(.+)/', $this->fn, $found) ? $found : array('', '', '', $found[0]); foreach($subdirs as $subdir) { $sub = _slashjoin($up, $subdir); # Wanneer de basis zoekdirectory niet bestaat, dan controleren we nog even # of deze naam niet partieel voorkomt ergens in de boom. Zie functie _dirlist(). if ($subdir and !is_dir($sub)) { $sub = _dirlist(dirname($sub), preg_replace('/([^0-9a-z]+)$/', '', $subdir) ); } $this->searchdir = _slashjoin($sub, $path); $exists = (file_exists($this->searchdir) and filesize($this->searchdir) > 0); if ($exists) { $this->searchpath = $sub; break; } } $readable = ($exists and is_readable($this->searchdir) ); $soort = ($readable) ? filetype($this->searchdir) : ""; if ($readable and $soort == "file") { $this->cached( join('', file($this->searchdir)) ); $this->error = null; } elseif (!$exists) { $this->error( sprintf("'%s' bestaat niet.", $this->searchdir) ); } elseif (!$readable) { $this->error( sprintf("'%s' kan niet worden gelezen.", $this->searchdir) ); } elseif ($exists && $soort != "file") { $this->error( sprintf("'%s' is geen geldig bestand; %s", $this->searchdir, $soort) ); } return; } function error($str) { $text = sprintf('%s %s [in %s]', $this->me, $str, $_SERVER['SCRIPT_NAME']); $this->error = $text; if ($_SERVER['IS_DEVEL'] and $this->error) error_log($this->error); } function parse($vars = array()) { $vars = $vars + $this->vars; if ($this->searchpath) # Voeg een slash toe aan het einde van het pad - templates verwachten dit! $vars['_searchpath'] = trim(_slashjoin($this->searchpath, ' ')); $match = array(); $repl = array(); foreach(array_keys($vars) as $key){ $match[] = sprintf("/(%%\[%s\]%%)/i", preg_quote($key)); $repl[] = $vars[$key]; } $match[] = '/%\[[^\[\]]+\]%/'; # Catch all $repl[] = ''; return preg_replace($match, $repl, $this->cached()); } function extractData() { $reg = '/<\!--(\s*([^=\s\<\>]+)[\s=]+[\'"]?([^\'"\s\<\>]+))+\s*-->/'; $comment = '/<\!--\s*(.+)\s*-->/'; $fields = '/([^=\s<>]+)[\s=]+([\'\"])?([^\s<>\2]+)/'; if (! preg_match_all($comment, $this->cached(), $found) ) return false; foreach($found[1] as $line) { preg_match_all($fields, $line, $res); for($i=0; $i < sizeof($res[0]); $i++) { $this->vars[$res[1][$i]] = $res[3][$i]; } } return $this->vars; } function cached($str = null) { if (is_null($str)) { #request $do = $this->inf; return ($this->compressed() and $this->ch) ? $do($this->ch) : $this->ch; } $do = $this->def; $this->ch = ($this->compressed()) ? $do($str, 9) : $str; } function compressed() { return ($this->inf || $this->def); } } # EOF ?> parse( // aanroep om "dailer.template.htm" te parsen # array( # "link" => $templateLink, // in het template bestand word "%[link]% vervangen door de waarde in $templateLink # ) # ); # ###### # Door: Willem de Vries # Date: 9 februari 2005 # Voor: Virtual Pc Services # Versie: 2.2 # ###### # Changelog: # 1.0 (WdV 7-11-2003): statische functie ombouwen naar object # 1.1 (WdV 13-2-2004): parsen moet ook zonder parameters kunnen # 1.2 (JF 15-2-2004): Set functie toegevoegd om variablen aan template toe te voegen, aaroep: set(variablenaam, value) # 1.3 (JF 24-3-2004): Endless loop bug gefixed, bij openen van template kwam hij bij lege file of file zonder # regeleinde niet bij eof bij lezen van filesize. # 1.4 (WdV 04-3-2005): Nieuwe functie om default-waardes uit een HTML-comment veld te halen. # 2.0 (WdV 09-2-2005): grotendeels herschreven refresh() en parse() routine. Nu 50% sneller! # 2.1 (WdV 15-2-2005): Mogelijkheid om een template aan te maken vanuit een string ipv. een file uit te lezen # 2.2 (WdV 28-10-2005): On-the-fly compressie om geheugen te sparen, kleinere array properties # 2.3 (WdV 15-12-2005): Gebruik van de "TEMPLATE_SEARCH" superglobal om een (relatief) zoekpad op te geven waarin # templates gezocht moeten worden. ############################################################### function _slashjoin() { $out = array(); foreach(func_get_args() as $param) { if ($param) $out[] = $param; } return preg_replace('#([/]+)#', '/', join('/', $out)); } function _dirlist($str, $regex = '.*') { $out = array(); $dh = (is_dir($str)) ? @opendir($str) : null; while ($dh and $fil = readdir($dh)) { $out[] = _slashjoin($str, $fil); } if ( !$out) return; list($item) = array_values(preg_grep("|$regex|i", $out)); # error_log(__FUNCTION__ . " Matching items for |$regex|"); # error_log(__FUNCTION__ . " Subdirs in $str: " . join('|', $out)); # error_log(__FUNCTION__ . " Found dir '$item'"); return ($item) ? $item : $str; } class Template { var $fn = null; var $filename = null; var $ch = null; var $error = null; var $searchpath = null; var $searchdir = null; var $inf = null; var $def = null; var $me = 'object'; var $vars = array(); function Template($name) { # Compatibility $this->filename =& $this->fn; $this->me = strtoupper(get_class($this)); $this->searchpath = $GLOBALS[$this->me . "_SEARCH"]; if (defined($this->me . "_COMPRESS")) { foreach(array(array('gzcompress', 'gzuncompress'), array('gzdeflate', 'gzinflate')) as $grp) { if (function_exists($grp[0])) { $this->def = $grp[0]; $this->inf = $grp[1]; break; } } } $this->fn = $name; $this->refresh(); } function set($varname, $value = ''){ $this->vars[$varname] = $value; } function get($varname) { return $this->vars[$varname]; } function refresh() { if (!preg_match('/\.([^\.\/\s]+)$/', $this->fn, $found) ) { $this->cached($this->fn); $this->fn = null; $this->error = null; return; } # Implementatie zoekpad $subdirs = preg_split('/([\s]*;[\s]*)/', $this->searchpath); if (! $subdirs) $subdirs = array(''); list($a, $up, $b, $path) = preg_match('/^(([\.]+\/)*)(.+)/', $this->fn, $found) ? $found : array('', '', '', $found[0]); foreach($subdirs as $subdir) { $sub = _slashjoin($up, $subdir); # Wanneer de basis zoekdirectory niet bestaat, dan controleren we nog even # of deze naam niet partieel voorkomt ergens in de boom. Zie functie _dirlist(). if ($subdir and !is_dir($sub)) { $sub = _dirlist(dirname($sub), preg_replace('/([^0-9a-z]+)$/', '', $subdir) ); } $this->searchdir = _slashjoin($sub, $path); $exists = (file_exists($this->searchdir) and filesize($this->searchdir) > 0); if ($exists) { $this->searchpath = $sub; break; } } $readable = ($exists and is_readable($this->searchdir) ); $soort = ($readable) ? filetype($this->searchdir) : ""; if ($readable and $soort == "file") { $this->cached( join('', file($this->searchdir)) ); $this->error = null; } elseif (!$exists) { $this->error( sprintf("'%s' bestaat niet.", $this->searchdir) ); } elseif (!$readable) { $this->error( sprintf("'%s' kan niet worden gelezen.", $this->searchdir) ); } elseif ($exists && $soort != "file") { $this->error( sprintf("'%s' is geen geldig bestand; %s", $this->searchdir, $soort) ); } return; } function error($str) { $text = sprintf('%s %s [in %s]', $this->me, $str, $_SERVER['SCRIPT_NAME']); $this->error = $text; if ($_SERVER['IS_DEVEL'] and $this->error) error_log($this->error); } function parse($vars = array()) { $vars = $vars + $this->vars; if ($this->searchpath) # Voeg een slash toe aan het einde van het pad - templates verwachten dit! $vars['_searchpath'] = trim(_slashjoin($this->searchpath, ' ')); $match = array(); $repl = array(); foreach(array_keys($vars) as $key){ $match[] = sprintf("/(%%\[%s\]%%)/i", preg_quote($key)); $repl[] = $vars[$key]; } $match[] = '/%\[[^\[\]]+\]%/'; # Catch all $repl[] = ''; return preg_replace($match, $repl, $this->cached()); } function extractData() { $reg = '/<\!--(\s*([^=\s\<\>]+)[\s=]+[\'"]?([^\'"\s\<\>]+))+\s*-->/'; $comment = '/<\!--\s*(.+)\s*-->/'; $fields = '/([^=\s<>]+)[\s=]+([\'\"])?([^\s<>\2]+)/'; if (! preg_match_all($comment, $this->cached(), $found) ) return false; foreach($found[1] as $line) { preg_match_all($fields, $line, $res); for($i=0; $i < sizeof($res[0]); $i++) { $this->vars[$res[1][$i]] = $res[3][$i]; } } return $this->vars; } function cached($str = null) { if (is_null($str)) { #request $do = $this->inf; return ($this->compressed() and $this->ch) ? $do($this->ch) : $this->ch; } $do = $this->def; $this->ch = ($this->compressed()) ? $do($str, 9) : $str; } function compressed() { return ($this->inf || $this->def); } } # EOF ?> parse( // aanroep om "dailer.template.htm" te parsen # array( # "link" => $templateLink, // in het template bestand word "%[link]% vervangen door de waarde in $templateLink # ) # ); # ###### # Door: Willem de Vries # Date: 9 februari 2005 # Voor: Virtual Pc Services # Versie: 2.2 # ###### # Changelog: # 1.0 (WdV 7-11-2003): statische functie ombouwen naar object # 1.1 (WdV 13-2-2004): parsen moet ook zonder parameters kunnen # 1.2 (JF 15-2-2004): Set functie toegevoegd om variablen aan template toe te voegen, aaroep: set(variablenaam, value) # 1.3 (JF 24-3-2004): Endless loop bug gefixed, bij openen van template kwam hij bij lege file of file zonder # regeleinde niet bij eof bij lezen van filesize. # 1.4 (WdV 04-3-2005): Nieuwe functie om default-waardes uit een HTML-comment veld te halen. # 2.0 (WdV 09-2-2005): grotendeels herschreven refresh() en parse() routine. Nu 50% sneller! # 2.1 (WdV 15-2-2005): Mogelijkheid om een template aan te maken vanuit een string ipv. een file uit te lezen # 2.2 (WdV 28-10-2005): On-the-fly compressie om geheugen te sparen, kleinere array properties # 2.3 (WdV 15-12-2005): Gebruik van de "TEMPLATE_SEARCH" superglobal om een (relatief) zoekpad op te geven waarin # templates gezocht moeten worden. ############################################################### function _slashjoin() { $out = array(); foreach(func_get_args() as $param) { if ($param) $out[] = $param; } return preg_replace('#([/]+)#', '/', join('/', $out)); } function _dirlist($str, $regex = '.*') { $out = array(); $dh = (is_dir($str)) ? @opendir($str) : null; while ($dh and $fil = readdir($dh)) { $out[] = _slashjoin($str, $fil); } if ( !$out) return; list($item) = array_values(preg_grep("|$regex|i", $out)); # error_log(__FUNCTION__ . " Matching items for |$regex|"); # error_log(__FUNCTION__ . " Subdirs in $str: " . join('|', $out)); # error_log(__FUNCTION__ . " Found dir '$item'"); return ($item) ? $item : $str; } class Template { var $fn = null; var $filename = null; var $ch = null; var $error = null; var $searchpath = null; var $searchdir = null; var $inf = null; var $def = null; var $me = 'object'; var $vars = array(); function Template($name) { # Compatibility $this->filename =& $this->fn; $this->me = strtoupper(get_class($this)); $this->searchpath = $GLOBALS[$this->me . "_SEARCH"]; if (defined($this->me . "_COMPRESS")) { foreach(array(array('gzcompress', 'gzuncompress'), array('gzdeflate', 'gzinflate')) as $grp) { if (function_exists($grp[0])) { $this->def = $grp[0]; $this->inf = $grp[1]; break; } } } $this->fn = $name; $this->refresh(); } function set($varname, $value = ''){ $this->vars[$varname] = $value; } function get($varname) { return $this->vars[$varname]; } function refresh() { if (!preg_match('/\.([^\.\/\s]+)$/', $this->fn, $found) ) { $this->cached($this->fn); $this->fn = null; $this->error = null; return; } # Implementatie zoekpad $subdirs = preg_split('/([\s]*;[\s]*)/', $this->searchpath); if (! $subdirs) $subdirs = array(''); list($a, $up, $b, $path) = preg_match('/^(([\.]+\/)*)(.+)/', $this->fn, $found) ? $found : array('', '', '', $found[0]); foreach($subdirs as $subdir) { $sub = _slashjoin($up, $subdir); # Wanneer de basis zoekdirectory niet bestaat, dan controleren we nog even # of deze naam niet partieel voorkomt ergens in de boom. Zie functie _dirlist(). if ($subdir and !is_dir($sub)) { $sub = _dirlist(dirname($sub), preg_replace('/([^0-9a-z]+)$/', '', $subdir) ); } $this->searchdir = _slashjoin($sub, $path); $exists = (file_exists($this->searchdir) and filesize($this->searchdir) > 0); if ($exists) { $this->searchpath = $sub; break; } } $readable = ($exists and is_readable($this->searchdir) ); $soort = ($readable) ? filetype($this->searchdir) : ""; if ($readable and $soort == "file") { $this->cached( join('', file($this->searchdir)) ); $this->error = null; } elseif (!$exists) { $this->error( sprintf("'%s' bestaat niet.", $this->searchdir) ); } elseif (!$readable) { $this->error( sprintf("'%s' kan niet worden gelezen.", $this->searchdir) ); } elseif ($exists && $soort != "file") { $this->error( sprintf("'%s' is geen geldig bestand; %s", $this->searchdir, $soort) ); } return; } function error($str) { $text = sprintf('%s %s [in %s]', $this->me, $str, $_SERVER['SCRIPT_NAME']); $this->error = $text; if ($_SERVER['IS_DEVEL'] and $this->error) error_log($this->error); } function parse($vars = array()) { $vars = $vars + $this->vars; if ($this->searchpath) # Voeg een slash toe aan het einde van het pad - templates verwachten dit! $vars['_searchpath'] = trim(_slashjoin($this->searchpath, ' ')); $match = array(); $repl = array(); foreach(array_keys($vars) as $key){ $match[] = sprintf("/(%%\[%s\]%%)/i", preg_quote($key)); $repl[] = $vars[$key]; } $match[] = '/%\[[^\[\]]+\]%/'; # Catch all $repl[] = ''; return preg_replace($match, $repl, $this->cached()); } function extractData() { $reg = '/<\!--(\s*([^=\s\<\>]+)[\s=]+[\'"]?([^\'"\s\<\>]+))+\s*-->/'; $comment = '/<\!--\s*(.+)\s*-->/'; $fields = '/([^=\s<>]+)[\s=]+([\'\"])?([^\s<>\2]+)/'; if (! preg_match_all($comment, $this->cached(), $found) ) return false; foreach($found[1] as $line) { preg_match_all($fields, $line, $res); for($i=0; $i < sizeof($res[0]); $i++) { $this->vars[$res[1][$i]] = $res[3][$i]; } } return $this->vars; } function cached($str = null) { if (is_null($str)) { #request $do = $this->inf; return ($this->compressed() and $this->ch) ? $do($this->ch) : $this->ch; } $do = $this->def; $this->ch = ($this->compressed()) ? $do($str, 9) : $str; } function compressed() { return ($this->inf || $this->def); } } # EOF ?>