Benamite
Benamite

Benamite

Benamite is ons systeem voor het afhandelen van URLs & content management. Je kan het zien als een soort van virtueel filesysteem, waarbij de url het path is en het bestand wat je vind de pagina die getoond wordt.

TODO:
- php haak verder toelichten
- contract van variabel entry special veld functie

Inhoudsopgave:

  • Soorten entries
  • Werking
  • Gebruik
  • PHP Haak

Soorten entries

Benamite kent verschillende soort entries, namelijk:

Map [vfsEntryDir]
Deze entry kan andere entries bevatten.
Verder kan een Map ook functioneren als zijnde een PHP Haak (zie hieronder). Als de Map zelf iets moet weergeven, maar geen Haak functionaliteit heeft, dan probeert hij dat te delegeren naar een sub-entry met de naam $INDEX ('index.html'). Als die sub-entry niet bestaat krijg je een 403.
Bestand (publisher) [vfsEntryFile]
Dit is een bestandje waarvan de inhoud in de DB zit.
De inhoud kan alleen bewerkt worden via publisher. Dit is dus altijd een HTML pagina die binnen de website layout weergegeven wordt.
Bestand (geupload) [vfsEntryUploaded]
Dit is een bestand dat via publisher geupload is.
De inhoud is opgeslagen onder /srv/http/www/benamite_files, voor het vinden wordt de hash van de content gebruikt. Als het bestand weer opgevraagd wordt dan wordt de content-mimetype gebruikt die de data had tijdens het uploaded.
Uploaden kan alleen in de publisher interface.
Link [vfsEntryLink]
Doet een redirect naar een andere plek op onze website.
In het speciale veld geef je aan waarnaar geredirect moet worden. Dit kan zowel een absoluut pad zijn (begint met /) of relatief ten opzichte van van de huidige locatie zijn.
Voorbeeld van een relatieve link: stel link zelf is te vinden op /foo/bar en hij verwijst naar aap/noot, dan wordt je bij bezoeken van http://a-eskwadraat.nl/foo/bar geredirect naar http://a-eskwadraat.nl/foo/aap/noot.
Bestand (op FS) [vfsEntryInclude]
Dit levert een bestand van het filesystem (onder /srv/http/www/www/, dan $HOME/wwwdebug/www/) op.
Er worden heuristieken toegepast om de content-type te bepalen. De belangrijkste heuristiek regel om te weten is dat als een bestand op .php eindigt, dan wordt deze gerequire_onced.
Het speciale veld kun je (optioneel) aangeven welke functie (of statische methode van een klasse) aangeroepen moet worden na de require_once.
De code in het bestand handelt het weergeven volledig af (inclusief de ->start() en ->end() aanroepen van de pagelayout).
Variabel [vfsEntryVar]
Deze entry heeft in de benamite UI altijd * als naam en staat ook altijd bovenaan gesorteerd. Deze entry krijgt pas een naam bij het verwerken van een URL (zie 'Werking' hieronder). In het speciale veld staat de functie die gebruikt wordt voor het valideren van de naam.
Deze entry kan, net als een Map, sub-entries hebben.
PHP Haak [vfsEntryHook]
Gedetaileerde uitleg over de hoe & wat van deze entry soort staat aan het einde van dit document. Kort gezegt is het een combinatie van Map en Bestand (op FS), maar dan met nog wat extra functionaliteiten en eisen.

Werking

In wwwdebug/www staat een .htaccess met een regel daarin die er voor zorgt dat apache niet zelf gaat proberen pagina's te vinden op het FS, maar dat ie www/space/space.php moet uitvoeren met de URL als parameter. space.php laad wat code en vraagt dan aan benamite, door middel van de hrefToReference functie, welke entry bij de URL hoort.

De functie hrefToReference splitst de URL op / en gaat dan deze stukjes een voor een verwerken. Dit is een recursief algoritme waarbij de boom van vfsEntries getraversed wordt. Onderweg worden toegang checks uitgevoerd, Link entries worden gevolgd, en bij Variable entries wordt de naam gechecked.

Het antwoord van hrefToReference heeft een aantal mogelijke gevolgen:

  • geen toegang, de bezoeker voldoet niet aan de minimum authorisatie level eis van een entry
    → space geeft een 403
  • de URL is niet helemaal verwerkt (er waren nog stukjes URL over) EN de diepst gevonden entry heeft GEEN haak functionaliteit
    → space geef een 404
  • we worden door geredrect naar een andere pagina. De url die bezocht wordt matched niet met de ->url() van de entry, dit kan komen door dat we een Link entry gevolgd hebben, of doordat de cAsInG in de ingetikte url niet matched met wat de gevonden entry
    → space geeft een 302 (redirect) naar de nieuwe/goede lokatie
  • in het overige geval wordt de ->display() van de gevonden entry aangeroepen.

Gebruik

Nu we weten wat benamite is en wat het werkt is het tijd om het gebruik toe te lichten.

URL's

Denk na over (& schrijf uit) de URL structuur van wat je gaat maken en wat er te getoond moet worden op de verschillende locaties.
Als (fictief?) voorbeeld deelnemers deel dat onder een activiteit zit:

    .../                                  [pagina met wat linkjes & statistiekjes]    .../Deelnemer                         [geen content: 403]    .../Deelnemer/Nieuw                   [form voor inschrijvingen]    .../Deelnemer/<lidnr>                 [redirect naar de Info pagina]    .../Deelnemer/<lidnr>/Info            [toon gegevens]    .../Deelnemer/<lidnr>/Wijzig          [wijzigen van de gegevens]  

Benamite

Nu gaan we de URL structuur uit stap 1 overzetten naar benamite.
Dit levert het volgende resultaat:

  1:  .../                            Map  2:  .../index.html                  Bestand (op FS)  3:  .../Deelnemer                   Map  4:  .../Deelnemer/Nieuw             Bestand (op FS)  5:  .../Deelnemer/*                 Variabel  6:  .../Deelnemer/*/index.html      Link                [naar Info]  7:  .../Deelnemer/*/Info            Bestand (op FS)  8:  .../Deelnemer/*/Wijzig          Bestand (op FS)  

Nummer 2 zorgt er voor dat je bij bezoeken van de URL van 1 een pagina te zien krijgt en niet een 403 (zoals bij 3). Doordat 6 een Link is kom wordt je bij het bezoeken van 5 door gestuurd naar 7.

Nummers 2, 4, 7 en 8 verwijzen in hun speciaal veld naar een php bestand (en mogelijk een specifieke klasse/functie daarin) die het weergeven afhandelt. Die heeft een standaard logica van:

  • form data afhandelen (optioneel)
  • data verzamelen
  • page->start() ; content ; page->end()
Denkend in ChopChop (WsW4) termen is de Controller logica die tenslote een View aanroept.

Het bijzondere geval is de Variabel entry van nummer 5. De methode waar het speciale veld naar verwijst bepaald ofdat wat er in de URL is ingevuld valide en toegankelijk is. In het voorbeeld zou de functie alleen lidnr's toestaan van mensen die deelnemer zijn.
TODO:EISEN van de speciale functie (params en return waarde) TODO

PHP Haak

Als wat je wilt doen niet kan met een combinatie van de andere entry soorten dan heb je mogelijk een PHP Haak nodig. Wat kan je met een PHP Haak:

  • Extra items in het menu tonen
  • URL & Content afhandeling overnemen van benamite
  • en nog wat exotische dingen die je zeer zeker niet nodig gaat hebben (de huidige use-case ervan is al zeer dubieus).

Het speciale veld van een PHP haak wijst altijd naar een functie in een bestand, of is het de prefix ervan. Voor het vinden van functionaliteit voor het aanpassen van het menu wordt namelijk aan de functienaam "_menu" toegevoegd, en voor de url & content afhandeling "_content".
Het is dus erg fijn als die addities niet gebruikt worden bij functie die niet bedoeld zijn voor gebruik in een PHP Haak.

Zowel het menu

een menu functie

Het is dus mogelijk dat de diepste entry die we vinden een PHP Haak is en als dat zo is, is het mogelijk dat we nog een stukje URL over hebben welke verwerkt moet worden. Dat is dus precies wat de haak gaat doen. In de benamite UI interface kun je zien dat het speciale veld iets in de vorm van '/path/bestand:functie' moet zijn. '/path/bestand' is het bestand wat we gaan include, 'functie' is de prefix van de hook functies.

Het verder verwerken van de URL en terug geven van content is namelijk een 'content hook' en daarom is de functie die in aangeroepen wordt 'functie_content'. Vb: de entry voor Leden heeft in het speciale veld staan: '/space/benamite/hooks/leden.php:leden', betekend dat de functie die aangeroepen gaat worden 'leden_content' is.

De content functie krijgt als (enige/eerste) parameter een array met daarin de stukjes URL (welke gesplists was op '/') die nog verwerkt MOETEN worden. Let op de extra nadruk op moeten! Dit zal dus een van de eerste dingen zijn die de content functie gaat doen[2]. Denk bv aan heeft $rest geen/te veel/te weinig elementen, als je lidnr verwacht check ofdat ie ook echt geldig is, ...
De volgende stap (kan verwerven zitten met het checken) is het iets terug geven aan de bezoeker. Dit kan van alles zijn: http meldingen (404, 403, 302, ...), HTML pagina's (vergeet niet de $page->start() en ->end() aan te roepen), of andere content... Om te voorkomen dat de content functie net zo'n beest wordt als dit verhaal is het handig om het de code die werkelijk iets gaat weergeven in een eigen functie (of View :D) te stoppen.

Naast de _content functie zijn er nog 3 opties. De nuttigste voor het maken van stukjes website is de menu haak. Korte uitleg daarvan vindt je in www/space/benamite/hooks/README

Bij een 'Bestand (op FS)' moet je code schrijven voor het afhandelen van (mogelijke) postdata, access control checks doen, $page->start() aanroepen, DB querien, content outputten, etc...

Bij een 'PHP Haak' moet je de (ALLE mogelijk vormen van de) rest van de URL correct verwerken en voor ELKE mogelijkheid ook nog het zelfde doen als 'Bestand (op FS)'. Met andere woorden: aanzienlijk meer werk.

[1] 'bestand (op FS)' heeft in zijn speciale veld op het moment alleen een het bestand wat geinclude wordt, maar ik denk dat ik er binnen kort iets van maak ala de php-haak notatie. Wat ik bedoel is dat er een ':functie' erachter mag staan, en dat als dat zo is dat dan na het include die functie aangeroepen wordt.

[2] Er zijn al een helper functie voor het geven van de bekende HTTP meldingen (404,..). Waarschijnlijk dat ik er nog een aantal bij ga maken, maar dan voor het verwerken van de (stukjes) url. Iets wat namelijk nu niet heel veel/goed gebeurt in de content hooks is het afhandelen van de casing (hoofdletter's e.d.) van stukjes URL. 'hrefToReference' checkt er wel op en zorgt ook dat space een redirect doet naar de plek met de goede spelling.

[3] Sorry voor de brakke/ambigue notatie van mij... komt omdat een HOOK !isa MAP maar wel MAP isA HOOK