Hi Sascha,
First I create an instance of Zend_View in the FrontController /
Bootstrap file and initialize and register it as follows:
$view = new Zend_View();
$view->setScriptPath(PATH_VIEW);
Zend::register('view', $view);
Then, in the ActionController I use the view via
$view = Zend::registry('view') ;
$view->baseUrl = $this->getRequest()->getBaseUrl();
$this->getResponse()->appendBody($view->render('index.php'));
This works pretty well, but every time I look at the code I have to
think "there must be a better way of doing this". I think the main
problem is the setScriptPath call which has to be made in each
ActionController otherwise.
So far for the first problem: Do you know any better way to use the
Zend_View class? How do you render your content?
Funnily enough I was just discussing many of the things you are
asking
in this post on the Zend MVC list and I'll use a few examples here:
http://www.nabble.com/Making-module-dispatcher-a-real-module-
dispatcher-tf3160098s16154.html
One thing you could consider that myself and others are doing is to
extend Zend_Controller_Action...
class ApplicationMainController extends Zend_Controller_Action
{
Gather all your general tools, main view template, auth,
whatever, etc stuff here
}
class SpecificController extends ApplicationMainController
{
Do your specific stuff here
}
Next is a topic also dealing with Zend_View. As we all know a page
doesn't simply consist of a static frame and some dynamic main
content
only. So, I'd need a way to render several "blocks" with
Zend_View and
compose these into a base template. I had two different approaches:
- Render everything into a big $view->content variable and output
$this->content in the template.
- Setup a $view->contentTemplate variable which indicates which
sub-template to use and set all required data in the main template.
I hope you know what I'm talking about because the code examples for
these points could get pretty long.
Also these approaches don't deal with additional content like
dynamic
navigation or login/logout in the margins (say non-main-content-
area).
Again the question is: How do you handle such rendering in your
applications?
In my main/base controller I have a single method to render what you
call a "static frame"...
public function renderLayout( $layout='layouts/base.html' )
{
$this->getResponse()
->setHeader('Content-Type', 'text/html')
->setBody( $this->_view->render( $layout ) );
}
...then in specific controllers that extend the main controller I can
just...
public function someAction()
{
...gather all view stuff...
$this->_view->content = 'directory.html';
$this->renderLayout( '/layouts/base_directory.html' );
}
...which allows me to have a default layout template and override it
where necessary.
My layout templates look a bit like...
<body>
<div id="container">
<?php echo $this->render( '/library/header.html') ?>
<div id="container2">
<?php echo $this->render( $this->content ); ?>
<div class="clearboth"></div>
<?php echo $this->render( '/library/footer.html' ); ?>
</div>
</div>
</body>
However you are quite right about the widget type bits like dynamic
navigation, e.g. a breadcrumb or login/logout and I've not yet
found a
satisfying solution to these. As I see it they are the kind of thing
Zend View Helpers should be there to deal with however if you read
this
wishlist post by Ralph Schindler...
http://www.nabble.com/Zend_Controller-wishlist-tf3176985s16154.html
...you'll notice he suggests a need for
Zend_Controller_Action_Helper. I
don't have an answer here however you'll find that you can cover
quite a
few things like getting data for login/logout bits from the base/main
controller I suggest.
Last but not least there's a topic I don't have any idea for: The
model.
...
$db->query("SELECT Id FROM User WHERE Password = '$password' AND
Username = '$username'");
...
$db->query("UPDATE Online SET LastAction = NOW() WHERE UserId =
$id");
or
$user = $userFactory->getUser($username, $password);
$onlineFactory->getRecord($user->getId())->setLastAction(time())-
>save();
Up to the point where it get's really dirty, I'd favor speed for
clean
code.
You are kind of asking a bunch of questions in there and I think your
main question is about organising the code. In short I'd put code
like
the above, eg for simplicity using Zend_Db_Table, into something
like...
class User extends Zend_Db_Table
{
}
which would live in models/user.php
...and I'd use it in a controller like so...
$where = $db->quoteInto('age <= ?', '20');
$order = 'first_name';
$count = 10;
$offset = 20;
$user_table = new User;
$users = $user_table->fetchAll($where, $order, $count, $offset);
I'm not specifically suggesting you use Zend_Db_Table or put what
looks
like authorisation code into a user class but hopefully you can
see how
the code can be divided up.
Are there any tutorials or documentations available on how to
handle
the model part in a somehow abstract but not completely slow way?
Rob Allen's tutorial is one of the most recent and thorough ZF
tutorials
that does include the model part...
http://akrabat.com/zend-framework-tutorial/
At last I'd like to apologize because I'm pretty sure these or
similar
questions were already asked and answered in the past, but I simply
can't find some matching documentation. In case you know of any
tutorials or links on the mentioned topics, I'd be glad to hear from
you :-)
No need to apologise, there are plenty of us asking the same
questions
including myself. I've only described my perspective on it and am
equally interested in other approaches.
Nick