redbullmarky Posted September 29, 2007 Share Posted September 29, 2007 Hi all I'm currently in the process of redeveloping my main CMS. The idea would be to have something ridiculously simple to use for the site/content administrators. now - i'm developing a sort of templating system. Each tag used in my template has a module to handle it and its args. For example - I might have something like {content name="pagebody" filters="nl2br" rows="10"}. Which would display the field 'pagebody' using nl2br when in view mode. Edit mode might react by providing a textarea with 10 rows. The default action for each tag would be 'main', but I could also do stuff like {content action="banners" type="skyscraper"}, etc. now - when these tags are written into templates, a template can be run in two modes - view and edit. so my question - what would be the best way to implement this? i thought about having a folder called, for example, 'content' with a content.php "controller" inside of it, and then seperating all my actions into seperate classes in the same folder called action.main.php, action.banners.php which each having a 'view' method, and optionally having an 'edit' method for use by the admin system which would return some sort of <input> field. /content - content.php (the module handler) - action.main.php (contains 'view' method and optional 'edit' method) any thoughts on my own suggestion? any pitfalls? any better ideas? the idea is to make it easy enough to add new modules in the future that react depending on which of the two modes, view or edit, the system is in. Cheers Mark Quote Link to comment Share on other sites More sharing options...
redbullmarky Posted September 29, 2007 Author Share Posted September 29, 2007 in addition - my other issues are what main classes should do what. each page in my site is stored in the DB with a parent, its data/content (TEXT type), and template filename to use. so trying to keep things nice and organised, I'm guessing i need an object to handle the pages, a templating class, etc - but as modules are set up via the templates, should my template class be responsible for running these modules whilst parsing it? or should my page object do this? i'm thinking i need a 'main' object that does all the legwork that can be called in either 'view' or 'edit' mode and its properties, etc would be different based on this. any thoughts on this basic structure, too? Quote Link to comment Share on other sites More sharing options...
448191 Posted September 29, 2007 Share Posted September 29, 2007 I think it's a pretty good idea (I might steal it from you ). It's a clever twist on Fowler's Template View using custom tags, that has potential. Fowler describes a more fine grained 'interface', even embedding conditional logic using custom tags. Your idea could be interpreted as template mapping to View Helpers. How I would do it: The custom tags map to View Helpers These View Helpers take Domain Objects (user, article, whatever) as their construction argument. More custom tags map to Helper methods Even more custom tags provide arguments Example: <model target="Cms_Article"> <command name="view" do="read" args="arg1=value1&arg2=value2/> <command name="edit" do="showEdit"/> <model> class Cms_Article_ViewHelper { private $article; public function __construct(Cms_Article $article){ $this->article = $article; } public function read($args = array()){ return "<h1>{$this->article->getTitle()}<h1><p>{$this->getBody($args)}<p>"; } public function edit($args = array()){ return " <form id='articleEdit' action='/Aricle/DoEdit/{$this->article->getId()}> <input name='title' value='{$this->article->getTitle()}'/> <textarea cols='{$args['cols']}>{$this->getBody($args)}</textarea> </form>"; } private function getBody($args){ return isset($args['filter'])? StringTools::filter($args['filter'], $this->article->getBody()) : $this->article->getBody(); } } The thing is, you will have to do some command/view mapping for this to work. Something like this would work: class FrontController { public static function run(){ //Resolve command into token $token = Router::resolve(); //Make command object $command = CommandFactory::factory($token); //Execute command $command->execute(); //Make view and provide it with business objects $view = View::factory($command->getDomain()); //Provide mapping data $view->set('command', $token->getCommandString()); //Render View $view->render(); } } Your View package should be capable of mapping business objects to View Helpers. Which doesn't have to be complicated if you rely on a a standard naming scheme, simply suffixing the class name with "_ViewHelper" could already work. A note on dir structure: as I've voiced in some other threads, I HIGHLY recommend the PEAR naming scheme. Please let me know if any of this is unclear. Quote Link to comment Share on other sites More sharing options...
redbullmarky Posted September 30, 2007 Author Share Posted September 30, 2007 i sort of get it. these tags don't necessarily need to be editable within the actual page, but more so from a seperate admin section. the idea being I have a master object where I pass in the request as well as the mode, and the data then available from that object differs depending on the mode. where i'm a little hazy is what the role of the template engine should be. should it be the tpl engine that renders the tags and runs the components in edit/view mode, or should this be done by the main object? would it be sensible to have two methods in my main object called, for example, 'renderPage' (which takes the data and renders the final output) and fetchElements (which would return some form of array of form fields). sorry if you've already covered that... Quote Link to comment Share on other sites More sharing options...
448191 Posted September 30, 2007 Share Posted September 30, 2007 I don't think I follow. Can you do some (pseudo) code? Quote Link to comment Share on other sites More sharing options...
redbullmarky Posted October 2, 2007 Author Share Posted October 2, 2007 lets say i have an object. I'll call it 'CMS'. So far I'm using a registry to pass around objects for session, db connection, user handling, etc. so: <?php $cms = new CMS($registry, 'view'); $out = $cms->render(); ?> would set up the CMS object and render/return the output, whilst: <?php $cms = new CMS($registry, 'edit'); $fields = $cms->fetchElements(); ?> would parse the templates/tags as the view mode would, with the difference that it ignores non-tags and returns an array of either HTML form elements, or instructions for a helper in my admin control panel to build the relevent form). i'm thinking also that, in addition to 'view' and 'edit', each tag could have an optional 'save' method for when evidence of a posted form (in edit mode) is detected, so that any processing (converting human dates to SQL dates or timestamps, for example) can be carried out and put into a queue for saving the page in one swoop. am i going off on tangents, considering how flexible things need to be? Quote Link to comment Share on other sites More sharing options...
448191 Posted October 4, 2007 Share Posted October 4, 2007 It seems a bit of an odd construction... With this, if I understand correctly, you're going down a road where the responsibility of template parsing, or calling the parser, is scattered throughout your app. Initiating the forming of a response is better at home in your front (or application) controller. It can delegate to a response class, which delegates the actual parsing to a view class, which delegates to various view helpers as required. If it's an editable form you want, do what I do: generate it from an XML source. From a CPL you can edit the elements, descriptions as well as validation rules. DTD: <!ELEMENT forms (form+)> <!ELEMENT form (input+)> <!ATTLIST form id ID #REQUIRED action CDATA #REQUIRED method (post|get) #IMPLIED feedback (0|1) #IMPLIED > <!ELEMENT input EMPTY> <!ATTLIST input name CDATA #REQUIRED type (id|text|password|textarea|checkbox|radio|select|submit|reset) #REQUIRED value CDATA #IMPLIED required (0|1) #IMPLIED maxlen CDATA #IMPLIED minlen CDATA #IMPLIED pregmatch CDATA #IMPLIED description CDATA #IMPLIED > Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.