[PHP/OOP] Applicatie-design: Pages & php-templates

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • raps
  • Registratie: April 2003
  • Laatst online: 06-09 19:51
Ik ben bezig met het opzetten van een web-applicatie. Ik loop daarbij tegen 2 probelemen aan. Ik zou jullie hierover graag om advies vragen.


1. Page construction
Mijn applicatie is volledig OOP, een korte omschrijving:
De Application class wordt aangeroepen. Deze initializeerd algemene classes: Database, Language (meertaligheid), User, Error & TempData. Deze classes worden toegekend aan variabelen van Application, welke toegankelijk is d.m.v. een Singleton. Application gaat vervolgens kijken welke pagina ingeladen moet worden.
Aan de andere kant van de applicatie heb ik objecten als HTMLTable, FormValidator, etc. Nu zit ik met het probleem dat ik niet goed weet hoe ik dit alles bij elkaar moet brengen.

Ik heb onderdelen die op meerdere pagina's verschijnen en pagina's bestaan vrijwel altijd uit meerdere onderdelen. Mijn idee was om dit te doen door middel van 2 soorten classes:
PHP:
1
2
3
4
5
6
7
8
9
class Page { //Interface for pages
   var $app;
   
   function Page(&$content) {
      $this->app = Application::getInstance();
   }
   function construct() {} // initiate/use page-elements
   function show() {}  // assign variables and include template(s)
}
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class PageElement { //Interface for page-elements
   var $app;
   var $content;
   
   function PageElement(&$content) {
      $this->app     =  Application::getInstance();
      $this->content =& $content;
   }
   function prepare() {} //[optional] get objects | determine what to do
   function action() {} //perform action
   function finish() {} //[optional]
   function output() { //return html to Page
      return $this->content;
   }
}
Een voorbeeld van een Page is UserRegistration. Dit is fysiek meer dan 1 pagina, maar voor de applicatie is dit 1 pagina. Deze pagina bestaat dan uit verschillende PageElements: RegistrationForm, RegistrationHelp, Banner, etc. en gebruikt verder bijvoorbeeld de FormValidator. Andere voorbeelden van PageElements zijn: LoginForm, TextItem, FAQ, Menu.
Ik loop tegen enkele problemen aan als ik dit wil uitvoeren:
  • Hoe bouw ik het best een pagina op met deze PageElements?
    Ik kan een grote array doorlopen waarin ze allemaal gedefinieerd staan en van elk object de interface doorlopen. Ik heb dan echter weinig controle over de objecten. Ik kan dan wel in de show-methode van ieder pageElement de output()-methode aanroepen.
  • Hoe moet ik dit doen als PageElement weer een PageElement bevat?
  • Is het wel verstandig om alle elementen aan een vaste interface te binden?
Over het algemeen ligt dit onderdeel van mijn applicatie-design me gewoonweg niet echt lekker. Wellicht hebben jullie ideeen hoe dit beter aan te pakken.


2. Template gebruik
Ik heb wat template-enginges gebruikt, maar ik ben hier niet zo over te spreken. Bij deze applicatie ga ik veel HTML-objecten gebruiken en deze opmaken d.m.v. CSS. Echter zullen sommige onderdelen toch in Templates ingedeeld moeten worden. Hiervoor wil ik PHP gebruiken.
Door de OO manier, kan ik in een output()-method geen eenvoudige include gebruiken... return include('template.tpl'); zal niet werken. Ik wil wel controle hebben over mijn templates en de output ervan. Zo zal een 'geparsedte' template toegekend moeten kunnen worden aan een variabele in een andere template.
Verder zit ik met het probleem hoe ik de layout van de hele pagina moet integreren in mijn design. Ik kan natuurlijk een header & footer includen voor en na iedere pagina. Het is alleen zo dat deze zelf ook bestaan uit PageElements en er enige interactie mogelijk moet zijn tussen de Header en een Page (of PageElement).


Beide punten zitten me nu al enige tijd dwars en ik kom er maar niet op een goede manier uit. Uiteraard heb ik het e.e.a. gezocht en gelezen. Ik heb het GoF boek naast me liggen (nog niet helemaal gelezen).
Voor allebei kan ik wel een of andere omweg verzinnen, maar ik ben bang dat ik dan op een gegeven moment vast loop of echt enorme omwegen moet gaan maken en dat is natuurlijk niet de bedoeling.

Alvast hartelijk bedankt!

Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

1.

Als ik die 2 opzetjes zie van de klassen die je hebt denk ik dat je nog een aantal zaken uit elkaar moet trekken. In je page-element voer je, als ik het goed begrijp, de actie uit en doe je ook je HTML output vanuit die klasse. Ik zou die zaken meer proberen te scheiden. Ikzelf werk bijvoorbeeld met een template klasse waar ik template blokken aan toe ken. Tijdens dat toekennen check ik binnen de block klasse eerst of dat blokje gecached is en of de data dus opnieuw opgehaald moet worden (de actie dus uitgevoerd moet worden) of dat het block gebruikt kan worden wat in de cache staat. Na het uitvoeren van deze handelingen heb je een aantal block objecten die op je pagina voorkomen waarin dus al behoorlijk wat informatie zit over een bepaald block ( of een block gecached is, eventueel de output als de cache nog geldig was.) Daarna ga ik de acties uitvoeren die nog uitgevoerd moeten worden. Dan worden de objecten aangemaakt die de logica van m'n applicatie bevatten en voer ik de nodige acties uit.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$template = new Template;

$header = new Block("test.tpl.php", 3);
$template->addBlock($header);

if(!$header->isCached())
{ 
                //Voer hier al je acties uit en ken de variabelen uit die acties toe aan je template klasse.
    $Array = array("A" => "B", "C" => "D","E" => "F"); 
    
        for ($i = 0; $i < 100; $i++) 
        { 
            $test[] = $Array;
        } 
    $template->set($test,"test"); 
}

$template->outputHTML();


Kort samengevat:
- Ken stukjes deel-template (blocks) toe aan een hoofdtemplate.
- Check of er blockjes gecached zijn en ken gecachte content toe aan een block.
- Ga dan pas aan de slag met de logica van je applicatie.

Hoe je dit inpast in je applicatie hangt verder van je framework af. Het voorbeeld wat ik hier geef is erg minimaal maar ik hoop dat duidelijk is wat de gedachte erachter is.

2.

Het opslaan van output binnen een block object doe ik als volgt.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Template {

    private $output;
    private $uncached_blocks = 0;
    private $blocks = array();
    private $vars = array();

//Function for putting template contents into a block object.
    public function buildBlocks()
    {
        extract($this->vars);
        foreach($this->blocks as $key => $value)
        {   
            //Only uncached blocks have to be build
            if(!$this->blocks[$key]->isCached())
            {
                print("NOT CACHED: BUILDING BLOCK:".$this->blocks[$key]->getBlockFileName()."<br>");
                ob_start(); 
                include($this->blocks[$key]->getTemplatePath().$this->blocks[$key]->getBlockFileName());
                $this->blocks[$key]->setContent(ob_get_contents()); 
                ob_end_clean();
                
                //create a cache file for the block
                $this->createCache($this->blocks[$key]);
            }
        }
    }

}


Dit is uiteraard niet de hele template klasse.

Ik loop dus door de blocks heen die de hoofdtemplate bevat en sla de outout van een block op door gebruik te maken van een output buffer. Hoop dat het niet te vaag is zoals ik het hier vertel... (zou me niks verbazen :P )

[ Voor 12% gewijzigd door Brakkie op 07-12-2004 16:02 ]

Systeem | Strava