SitePoint Sponsor

User Tag List

Results 1 to 23 of 23
  1. #1
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Another Composite Question!

    Whats wrong with creating a page controller that can recurse its parent and traverse its children?

    This example does not fully work yet but thought I'd post it before completing it so people can get an idea pf what I'm trying to do:

    PHP Code:
    <?php
    class Action extends Controller {
        var 
    $id;
        var 
    $data     = array();
        var 
    $parent   NULL;
        var 
    $children = array();
        
        function 
    setId($value) {
            
    $this->id $value;
        }
        
        function 
    getId() {
            return 
    $this->id;
        }
        
        function 
    set($key$value) {
            
    $this->data[$key] =& $value;
        }

        function 
    get($key$value) {
            return (isset(
    $this->data[$key]) ? $this->data[$key] : NULL);
        }

        function 
    render($filename) {
            
    $this->recurse($this);
            
            
    $this->traverse($this);
            
            
    $this->response->set($this->fetch($filename));
        }
            
        function 
    fetch($filename) {
            
    $file DIR_VIEW $filename;
        
            if (
    file_exists($file)) {
                  
    extract($this->data);

                  
    ob_start();
          
                  include(
    $file);
          
                  
    $content ob_get_contents();

                  
    ob_end_clean();

                  return 
    $content;
            } else {
                  exit(
    'Error: View ' $file ' not found!');
            }
        }
        
        function 
    attach(&$child) {
            
    $this->children[$child->getId()] =& $child;
        }

        function 
    getChildren() {
            return 
    $this->children;
        }
        
        function 
    create() {
        
        }
        
        function 
    recurse(&$controller) {
            if (
    $this->parent) {
                
    $parent $this->create($this->parent);
            
                
    $parent->attach($this);
                
                
    $parent->execute();
            }
        }
        
        function 
    traverse(&$controller) {
            
    $children $controller->getChildren();
            
            foreach (
    $children as $child) {
                
    $this->traverse($child);
                
                
    $child->execute();
                
                
    $controller->set($child->getId(), ob_get_clean());
            }    
        }
    }

    class 
    ControllerHome extends Action {
        
    $id 'content';
        
        function 
    index() {
            
    $this->parent 'layout';
            
            
    $this->data['message'] = 'Hello World!';
            
            
    $this->render('content/home.tpl');
        }
    }

    class 
    ControllerLayout extends Action {
        
    $id 'layout';
        
        function 
    index() {
            
    $this->children = array(
                
    'header',
                
    'footer',
                
    'content'
            
    );    
            
            
    $this->render('layout/default.tpl');
        }
    }
    ?>
    Last edited by blueyon; Nov 27, 2007 at 13:55.

  2. #2
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It doesnt really matter. Tree traversal (what this basically is) can be done in a number of ways.

    Aslong as you can find the parent (root) traversing through it should be no problem.

    easiest would be to let render() just find the root and ask the root to render everything.

    It seems this is what you are doing now but I havent looked at it properly yet.

  3. #3
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I like your idea.

    Do you this method in your controllers?

    A problem I have found is that each method in the controller might not require a parent or may require a differn't parent. I would need to execute each controller before finding out the parent.

  4. #4
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I tried to write something up and its pretty limited right now and not really tested well.

    Anyway what im doing when render() is called it looks for a root. When the root is found it calls traverse to get the data from its children and their children etc.

    PHP Code:
    class ViewComposite
    {
        
    //the parent (also a viewComposite)
        
    protected $parent;
        
        
    //children (viewComposite)
        
    protected $children = array();
        
        protected 
    $registry;
        
        
    //data for this particular view
        
    protected $data = array();

        
        public function 
    __construct($registry)
        {
            
    $this->registry $registry;
            
    $this->init();
        }
        
        protected function 
    init()
        {
            
    //actually used for setting defaults
        
    }
        
        public function 
    hasParent()
        {
            return isset(
    $this->parent);
        }
        
        public function 
    getParent()
        {
            return 
    $this->parent;
        }
        
        public function 
    setParent($view)
        {
            
    $this->parent $view;
        }
        
        public function 
    getRoot()
        {
            
            
    $node $this;
            while(
    $node->hasParent())
            {
                
    $node $node->getParent();
            }
            return 
    $node;
        }
        
        public function 
    hasChildren()
        {
            return (
    count($this->children) > 0);
        }
        
        protected function 
    getChildren()
        {
            return 
    $this->children;
        }
        
        public function 
    attach($name,$view)
        {
            
    $view->setParent($this);
            
    $this->children[$name] = $view;
            
        }
        
        protected function 
    traverse($node)
        {
            if(
    $node->hasChildren() == true)
            {
                
    $children $node->getChildren();
                foreach(
    $children as $key => &$child)
                {
                    
    $node->data[$key] = $child->render($child); 
                }            

            }
        }
        
        protected function 
    getOutput($node)
        {
            if(isset(
    $node->template))
            {
                
    $tpl = new Template($node->template);
                foreach(
    $node->data as $key => $value)
                {
                    
    $tpl->add($key,$value);
                }
                return 
    $tpl;
            }
        }
        
        public function 
    render($node null)
        {
            
            if(
    $node == null)
            {
                
    $node $this->getRoot();
                
            }    
            
    $this->traverse($node);
            return 
    $this->getOutput($node);    
        }
    }


    //code usage: (the registry gets the class,ignore it)
    $view $this->registry->getClass('testView');
            
    $view->attach("content",$content $this->registry->getClass('test2View'));
            
    $content->attach("moo",$this->registry->getClass('test3View'));
            
            
    //note this is in the middle of the tree
            
    echo $content->render(); 
    This will find the root and traverse it from there.
    A little side effect that might be useful is the you can render parts in your tree by giving the view to render() which you want to act as root.

  5. #5
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is quite good!

    I should be able to put something together after seeing this.

    Thank you!

  6. #6
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Please can you post an example of how you would use this inside a controller?

  7. #7
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    My class doesnt do anything useful except putting strings directly on a template. Ill write up something when i get back home.

  8. #8
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok an example:

    PHP Code:
    class Home extends Controller 
    {
    //your action
        
    public function view2()
        {
            
    $view $this->registry->getClass('testView');
            
    $view->attach("content",$content $this->registry->getClass('test2View'));
            
    $content->attach("moo",$this->registry->getClass('test3View'));
            
    //note this is in the middle of the tree
            
    echo $content->render();
        }

    The Views:
    PHP Code:
    class testView extends ViewComposite 
    {
        protected function 
    init()
        {
            
    $this->template "base.php";
            
    //some variable
            
    $this->data['name'] = "Name";
        }
        
    }

    class 
    test2View extends ViewComposite 
    {
        public function 
    init()
        {
            
    $this->template "content.php";
        }
    }

    class 
    test3View extends ViewComposite 
    {
        public function 
    init()
        {
            
    $this->template "moo.php";
        }

    - base.php has a $content variable somewhere.
    - content.php has a $moo variable somewhere.
    - moo.php has just text.

    tesView is the base and i tell it to attach test2View to it. then i attach test3View to test2View.
    Code:
    tree structure:
    testView
    	test2View
    		test3View
    now when i call $content->render() it goes from test2View to the root which asks to render everything.

    Now what i usually is build most of my template in the View so it would look something like this:

    PHP Code:
    class test2View extends ViewComposite 
    {
        public function 
    init()
        {
            
    $this->template "content.php";
            
    $this->setParent($this->registry->getClass("testView")); //the layout
            
    $this->attach("moo",$this->registry->getClass("test3View")); //something i want to include in the content
        
    }

    My controller looks something like this:
    PHP Code:
    class Home extends Controller 
    {
        public function 
    view2()
        {
            
    $content $this->registry->getClass('test2View');
            echo 
    $content->render();
        }

    So my controller doesnt really care how the output looks. I mean it can give variables to the view to set certain stuff (note: those arent built in right now you need to set some set() and get() functions).

    I usually just give basic info like a userId if it needs to display a user and let the View get the data that it needs.

    Also for certain AJAX (or AHAH or whatever) calls and you only need the content and not the layout you can do:
    PHP Code:
    $content->render($content); 
    This way $content acts as root and wont render testView.

  9. #9
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm trying to create a page controller that will recurse up to its parent and traverse its children.

    The problems I'm having is that its creating classes more than once.

    I have been trolling the forums, but can not seem to implement what I'm trying to do. I have seen many of Dr Livingstons composite examples, but I think they all need to start at the root rather than being able to start the composite tree from the middle.

    I have no problem attaching the child controllers and traversing them, but my system keeps creating classes more than once.

    Can some one give me an example of how I would do this?

    This is the code from one of my controllers.

    PHP Code:
    <?php
    class ControllerLogin extends Action {
        var 
    id       'content';
        var 
    $parent  'layout';
        var 
    $chilren = array();
        var 
    $data    = array();
        
        function 
    execute() {
            if (
    $this->request->isPost() && $this->user->login($this->request->get('email''post'), $this->request->get('password''post'))) {
                
    $this->redirect($this->url->href('controller=back_order'));
            }
            
            
    $this->data['action'] = $this->url->href('login');
            
            if (
    $this->request->has('email''post')) {
                
    $this->data['email'] = $this->request->get('email''post');
            } else {
                
    $this->data['email'] = '';
            }

            
    $this->render('content/login.tpl');
        }
    }
    ?>
    Last edited by blueyon; Dec 5, 2007 at 07:42.

  10. #10
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Could you show what you have tried so far? Specifically how you traverse it.

  11. #11
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have attached a coding sample.

    It works to the point of getting the main content, but it should also show the layout and all the sub parts.
    Attached Files Attached Files

  12. #12
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, the structures I build using Composite are traversed from top downwards or so it would appear... In fact the way the traversal works is from bottom upwards, to the top so it's always the children that get processed first.

    However, that doesn't help you if you require to begin your traversal midway through; May I ask why you want to do something like this? The one thing that does spring to mind is Observer where you'd pull out the specific Composite in question.

    That is what I used in the past, to replace one Composite with another one based on some logic, but nowadays, what I do is just to encapsulate that given Composite it's self within another one - Decorator - and leave it to the Decorator to decide what to do instead, which is more simpler.

    > ..., but my system keeps creating classes more than once.

    What do you mean? Are you creating a new Composite on-the-fly? Or... ?

  13. #13
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    However, that doesn't help you if you require to begin your traversal midway through; May I ask why you want to do something like this? The one thing that does spring to mind is Observer where you'd pull out the specific Composite in question.
    The content is the first of the composite controllers that gets dispatched. It has a parent called layout, but layout has lots of children like header, footer, column etc..

    I don't want to create a controller more than once.

    I'm not sure if it matters if the controller is executed before being attached or calls its children. Any solution would be good.

  14. #14
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you donwload the attachment it might give you a better idea of whats happening.

  15. #15
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > I don't want to create a controller more than once.

    Encapsulate that, that doesn't change in that case; You don't have to build the entire structure as is in the Controller though. Build it from elsewhere, and pass it into the Controller, and then attach that structure - the common garden layout - to your parent that way?

    The way I look at it, is that it's not an event in of it's self in regards to the structure. What I mean, is that you can pick your structure as and when required, so what you have is lots of Factories that build a given specific part and nothing more;

    You chop and change the Factories you use as you go along so to speak? I said earlier in another thread, that because Composite parts are treated as a whole, regardless there is little to the Factories themselves, bar what particular Composite the Factory builds.

    In my case, it's simply passing an array to the constructor and nothing more, where this array holds the child Composites for that parent - by that I don't mean the root but the Composite any children are attached to, so in that point you could have many parents

    Here is what I am talking about...

    PHP Code:
    // this is the root...
    final class QAction_Handler_Page extends QAction_Handler {
            public function 
    __construct() {
                
    $this -> id 'phptag:page';
            }
            
            public function 
    executeQContext $context ) {
                
    $page = new QPage_View$request $context -> get'request' ) );
                
    $page -> render'template.tpl' );
            }
        } 
    It does nothing basically bar holding a generic template shell, so you need children? Here is how child Composites are attached, in an automated manner,

    PHP Code:
    final class QAction_Handler_Root_Assembly extends QAction_Handler_Assembly {
            public function 
    __construct() {
                
    parent::__construct( array( 'meta''navigation''body' /* child composites */ );
            }
            
            protected function 
    create() {
                return new 
    QAction_Handler_Root();
            }
        }

    // abstraction
    abstract class QAction_Handler_Assembly {
            protected 
    $children = array();
            
            public function 
    __construct$children ) {
                
    $this -> children $children;
            }
            
            public function 
    get() {
                
    $args func_get_args();
                
    $parent array_shift$args );
                
    $composite $this -> create();
                if( 
    $parent instanceof QAction_Handler_Interface ) {
                    
    $parent -> attach$composite );
                }
                
                foreach( 
    $this -> children as $child ) {
                    
    $classname $this -> formatName$child );
                    
    $instance = new $classname(); 
                    
    $instance -> get$composite );
                }
                
                return 
    $composite;
            }
            
            protected function 
    formatName$name ) {
                return 
    'QAction_Handler_'.ucwords$name ).'_Assembly';
            }
            
            abstract protected function 
    create();
        } 
    So, I only need to do

    PHP Code:
    // ...
    $page = new QAction_Handler_Root_Assembly();
    return 
    $page -> get(); // and i'm done 
    If you have a different body then just use include(); to include that given Composite prior to creating the structure - this is what I do. Hope I've answered some of your questions, if not then let me know.

    > If you donwload the attachment it might give you a better idea of whats happening.

    Okay, will take a look

  16. #16
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm still not sure how to implement this with my front controller. Please can you give a another example.

    My system has a front controller which then executes a action controller. Now this action controller does not always need a full page or need to display anything unless its suposed to. With the page action handler below it seems to load everything.

    I still have your code from previous posts and got it working:

    PHP Code:
    <?php
    error_reporting
    (E_ALL);

    interface 
    QComposite_Interface {
        public function 
    getId();

        public function 
    getChildren();

        public function 
    hasChildren();

        public function 
    attach(QComposite_Interface $composite);
    }

    abstract class 
    QComposite implements QComposite_Interface {
        protected 
    $children = array ();
        protected 
    $id;

        public function 
    __construct() { 
        
        }

        public function 
    getId() { 
            return 
    $this->id
        }

        public function 
    getChildren() { 
            return 
    $this->children
        }

        public function 
    hasChildren() { 
            return 
    count($this->children); 
        }

        public function 
    attach(QComposite_Interface $composite) {
            
    $this->children[$composite->getId()] = $composite;
        }
    }

    interface 
    QAction_Handler_Interface extends QComposite_Interface 

    }

    abstract class 
    QAction_Handler implements QAction_Handler_Interface {
        protected 
    $children = array();
        protected 
    $id;

        public function 
    __construct() { 
        
        }

        public function 
    getId() { 
            return 
    $this->id
        }

        public function 
    hasChildren() { 
            return 
    count($this->children); 
        }

        public function 
    getChildren() { 
            return 
    $this->children
        }

        public function 
    attach(QComposite_Interface $composite) {
            
    $this->children[$composite->getId()] = $composite;
        }

        public function 
    traverse(&$controller) { 
            
    $children =& $controller->getChildren();

            foreach (
    $children as &$child) {
                
    $this->traverse($child);
                
                
    $child->execute();
            }
        }
        
        abstract public function 
    execute();
    }

    abstract class 
    QAction_Handler_Factory {
        protected 
    $children = array();

        public function 
    __construct($children) {
            
    $this->children $children;
        }

        public function 
    get() {
            
    $args      func_get_args();
            
    $parent    array_shift($args);
            
    $composite $this->create();

            if (
    $parent instanceof QAction_Handler_Interface) {
                
    $parent->attach($composite);
            }

            foreach (
    $this->children as $child) {
                
    $classname $this->formatName($child);
                
    $instance  = new $classname();
                
                
    $instance->get($composite);
            }
        
            return 
    $composite;
        }

        protected function 
    formatName($name) { 
            return 
    'Q' ucwords($name) . '_Factory'
        }

        abstract protected function 
    create();
    }

    final class 
    QPage_Factory extends QAction_Handler_Factory {
        public function 
    __construct() { 
            
    $children = array (
                
    'head',
                
    'body',
                
    'menu'
            
    );
        
            
    parent::__construct($children); 
        }

        protected function 
    create() { 
            return new 
    QPage_Action_Handler(); 
        }
    }

    final class 
    QHead_Factory extends QAction_Handler_Factory {
        public function 
    __construct() { 
            
    parent::__construct(array()); 
        }

        protected function 
    create() { 
            return new 
    QHead_Action_Handler(); 
        }
    }

    final class 
    QBody_Factory extends QAction_Handler_Factory {
        public function 
    __construct() { 
            
    parent::__construct(array('search')); 
        }

        protected function 
    create() { 
            return new 
    QBody_Action_Handler(); 
        }
    }

    final class 
    QMenu_Factory extends QAction_Handler_Factory {
        public function 
    __construct() { 
            
    parent::__construct(array()); 
        } 

        protected function 
    create() { 
            return new 
    QMenu_Action_Handler(); 
        }
    }

    final class 
    QSearch_Factory extends QAction_Handler_Factory {
        public function 
    __construct() { 
            
    parent::__construct(array()); 
        }

        protected function 
    create() {
            return new 
    QSearch_Action_Handler(); 
        }
    }

    final class 
    QPage_Action_Handler extends QAction_Handler {
        public function 
    __construct() {
            
    $this->id 'page';
        }

        public function 
    execute() { 
            echo 
    $this->id;
            
            
    $this->traverse($this);
        }
    }

    final class 
    QHead_Action_Handler extends QAction_Handler {
        public function 
    __construct() {
            
    $this->id 'head';
        }

        public function 
    execute() { 
            echo 
    $this->id;
        }
    }

    final class 
    QBody_Action_Handler extends QAction_Handler {
        public function 
    __construct() {
            
    $this->id 'body';
        }

        public function 
    execute() { 
            echo 
    $this->id;
        }
    }

    final class 
    QSearch_Action_Handler extends QAction_Handler {
        public function 
    __construct() {
            
    $this->id 'search';
        }

        public function 
    execute() { 
            echo 
    $this->id;
        }
    }

    final class 
    QMenu_Action_Handler extends QAction_Handler {
        public function 
    __construct() {
            
    $this->id 'menu';
        }

        public function 
    execute() { 
            echo 
    $this->id;
        }
    }

    $page_factory = new QPage_Factory();
    $page =& $page_factory->get();

    $page->execute();
    ?>

  17. #17
    SitePoint Enthusiast
    Join Date
    Mar 2007
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If i read the code correctly the factory predefines its children and will always traverse the given children. If you want more flexibility your can either make a new generic factory that allows for different children to be set or skip the factory.

    Or i read it all wrong which is not entirely impossible at this time

  18. #18
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I managed to get working what I was trying to do. I just want to ask peoples advice first weather they think what I have done is a good idea or not?

    Basicly the controller I have created before executing an action it checks to see if there is a parent controller and if so attachs the action controller to that. It then checks for child controllers and attaches them. Once everything is attached it executes all controllers starting from the children and working its self up until it gets to the root node.

    I will post examples once I have cleaned the code.

  19. #19
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Dr Livingston,

    As I'm creating my front contoller it looks like it might be easier to use a action chain rather than the composite pattern.

    If i create a list of pre actions and post actions for each action to load up the relavent controllers and fill in my view.

    What do you think?

    I have managed to pull off creating a tree from one of the sub controllers and not the root. When I look at the system it looks like I can give my self more flexibility from creating a action stack.

  20. #20
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Composite or Pre / Post Actions better for building up your view?

  21. #21
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Composite. Definitely.

    With your pre and post actions I am assuming they are in a chain? If that is so, then it'd be more difficult to construct your page in my view since your page it's self isn't a flat structure, in that how it's seen.

    I would stick with Composite, as once you move away from it you lose too many advantages.

  22. #22
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I managed to put this together. I don't know if you are supposed to do it this way.

    PHP Code:
    <?php
        
    function execute($action) {
            
    $action $this->get($action);
            
            
    $this->taverse($action);
        }
        
        function 
    get($key) {
            
    $action $this->create($key);
            
            
    $children = array();

            foreach (
    $action->children as $child) {
                
    $children[$child] = $this->get($child);
            }
            
            
    $action->children $children;
            
            if (
    $action->parent) {
                
    $parent $this->get($action->parent);
                
                
    $parent->children[$action->id] = $action;
                
                return 
    $parent;
            } else {
                return 
    $action;
            }
        }
        
        function 
    create($key) {
            
    $file $this->directory basename($key) . '.php';
            
    $class 'Controller' preg_replace('/[^a-zZ-Z0-9]/'NULL$key);
             
            if (
    file_exists($file)) {
                include_once(
    $file);
                
                
    $action = new $class($this->registry);
            } else {
                
    $action $this->create($this->error);
                
                
    $this->error NULL;
            }
            
            return 
    $action;
        }

          function 
    traverse(&$controller) {
            
    $children =& $controller->getChildren();
            
            foreach (
    $children as &$child) {
                
    $this->traverse($child);
                
                
    $child->execute();
            }
        } 
    ?>
    It goes in the front controller and will build up composite tree ready to be traversed. You can start it from the root or one of its nodes.

  23. #23
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    Composite. Definitely.

    With your pre and post actions I am assuming they are in a chain? If that is so, then it'd be more difficult to construct your page in my view since your page it's self isn't a flat structure, in that how it's seen.

    I would stick with Composite, as once you move away from it you lose too many advantages.
    Sorry to keep hasling you like this!

    How do you add the title to the main layout?

    I'm still not 100% sure how to make this work. I can get it working but the request calls a action from the content and not the page which is the root.

    Please advise?


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •