Johan,
I'm looking into it right now. Thanks for the report.
David
Am 30.01.2007 um 11:56 schrieb Johan Nilsson:
> Hi,
>
> Im using smarty as template engine, and there seems to be some
> problems with the new template implementation in the 0.11 branch;
>
> in AgaviSmartyRenderer::render the return statements is retrieving the
> file from the method $layer->getResourceStreamIdentifier() this
> returns something like file://c: (im on windows)
> unfortunately smarty cannot parse this it needs the path from c:/...
> so for now i simply added a str replace for file://.
>
> After that i could retrieve my templates, but then the 'template'
> variable where not assigned to the template. When using {DEBUG} in top
> of the template it clearly says "assigned template variables: no
> template variables assigned".
>
> Am I missing something?
>
>
> /johan
>
>
> On 1/30/07, David Zülke <[EMAIL PROTECTED]> wrote:
>> As of http://trac.agavi.org/changeset/1609, the output of the inner
>> layer is available via the variable $inner in templates. Also
>> available are $container for the current execution container and
>> $view for the template's view. Like with factories, the names of
>> these assigns ("inner", "container" and "view") can be configured
>> using the "assigns" parameter of a renderer.
>>
>> Since the wrapping template now does not have to know the inner
>> layer's name anymore, the example can be simplified quite a bit.
>>
>> Master.php:
>> <html>
>> <head><title>logs!</title></head>
>> <body>
>> <?php echo $inner; ?>
>> </body>
>> </html>
>>
>> LiveSuccess.php:
>> <tbody>
>> <?php foreach($t['messages'] as $message): ?>
>> <tr>
>> <td class="name"><?php echo $message->getNick()-
>> >getNick(); ?></td>
>> <td class="message"><?php echo $message->getMessage
>> (); ?></td>
>> <td class="time"><?php echo $message-
>> >getMessageDate(); ?></td>
>> </tr>
>> <?php endforeach; ?>
>> </tbody>
>>
>> LiveSuccess.wrapper.php:
>> <div id="roomTitle"><?php echo $t['topic']; ?></div>
>> <table border="0" cellspacing="0" cellpadding="0">
>> <?php echo $inner; ?>
>> </table>
>>
>> And the code that makes it happen:
>> public function executeHtml(AgaviRequestDataHolder $rd)
>> {
>> // remember: first, you should have a base view and call a
>> method on
>> the parent to load the layout instead of doing it here.
>> // second, loadLayout() would be enough since "standard"
>> is the
>> default layout
>> $this->loadLayout('standard');
>>
>> // now we insert the wrapper template between the
>> decorator and the
>> actual content layer
>> $i = $this->appendLayer($this->createLayer
>> ('AgaviFileTemplateLayer', 'wrapper'), $this->getLayer('content'));
>> $i->setTemplate('LiveSuccess.wrapper');
>> }
>>
>>
>> Cheers,
>>
>> David
>>
>>
>>
>> Am 29.01.2007 um 14:02 schrieb David Zülke:
>>
>>> Hi guys,
>>>
>>> I thought I'd give you a little example of what the new template
>>> layer system can do.
>>>
>>> We participated in the PHP Throwdown (http://www.phpthrowdown.com)
>>> and built an IRC bot using Agavi. It's called "Chuckwalla", contains
>>> a fully fledged IRC library that doesn't suck, has live logs, cool
>>> web interfaces etc and will be open sourced soon.
>>>
>>> One feature is the live logs. You click a channel, and it uses Ajax
>>> to refresh the contents, so you can follow the discussion in a
>>> channel. So for the first load, we need a full document, and for
>>> subsequent XMLHttpRequest, we just want the new messages.
>>>
>>> Here is the layout's configuration for output type "html":
>>> <layout name="standard">
>>> <layers>
>>> <layer name="content"
>>> class="AgaviFileTemplateLayer" />
>>> <layer name="decorator"
>>> class="AgaviFileTemplateLayer">
>>> <parameter name="template">Master</parameter>
>>> </layer>
>>> </layers>
>>> </layout>
>>>
>>> Let's assume this is our decorator template:
>>> <html>
>>> <head><title>logs!</title></head>
>>> <body>
>>> <?php echo $slots['content']; ?>
>>> </body>
>>> </html>
>>>
>>> And here is the content template (LiveSuccess.php):
>>> <div id="roomTitle"><?php echo $t['topic']; ?></div>
>>> <table border="0" cellspacing="0" cellpadding="0">
>>> <tbody>
>>> <?php foreach($t['messages'] as $message): ?>
>>> <tr>
>>> <td class="name"><?php echo $message-
>>> >getNick()->getNick(); ?></td>
>>> <td class="message"><?php echo $message-
>>> >getMessage(); ?></td>
>>> <td class="time"><?php echo $message-
>>> >getMessageDate(); ?></td>
>>> </tr>
>>> <?php endforeach; ?>
>>> </tbody>
>>> </table>
>>>
>>> Now we also have an output type for the AJAX calls, called "json".
>>> It's configured like this:
>>> <layout name="standard">
>>> <layers>
>>> <layer name="content"
>>> class="AgaviFileTemplateLayer" />
>>> </layers>
>>> </layout>
>>>
>>> But now we have a problem: If an AJAX call is made, we get back the
>>> entire inner content template, complete with the <divs> and the
>>> <table>, but we only want the <tbody> to append to the current table
>>> (remember, tables can have multiple <tbody> elements).
>>>
>>> One approach would be to simply have two templates. The other
>>> approach would be to split them up and include() the inner
>>> portion in
>>> the non-ajax version, and set the templates differently per output
>>> type.
>>>
>>> However, there also is a third approach. Right now, we have these
>>> layers:
>>> +------------------------+
>>> | <html> decorator |
>>> | +--------------------+ |
>>> | | <table> content | |
>>> | | with <tbody>, <tr> | |
>>> | +--------------------+ |
>>> | </html> |
>>> +------------------------+
>>>
>>> What we can do now is split up the template like we would with the
>>> include() solution:
>>> +------------------------+
>>> | <html> decorator |
>>> | +--------------------+ |
>>> | | <table> wrapper | |
>>> | | +----------------+ | |
>>> | | | <tbody> inner | | |
>>> | | | content | | |
>>> | | +----------------+ | |
>>> | | </table> | |
>>> | +--------------------+ |
>>> | </html> |
>>> +------------------------+
>>>
>>>
>>> First, the "wrapper" template (LiveSuccess.wrapper.php):
>>> <div id="roomTitle"><?php echo $t['topic']; ?></div>
>>> <table border="0" cellspacing="0" cellpadding="0">
>>> <?php echo $slots['inner']; ?>
>>> </table>
>>>
>>> And the actual "inner" content template (LiveSuccess.php):
>>> <tbody>
>>> <?php foreach($t['messages'] as $message): ?>
>>> <tr>
>>> <td class="name"><?php echo $message->getNick()-
>>> >getNick(); ?></td>
>>> <td class="message"><?php echo $message->getMessage
>>> (); ?></td>
>>> <td class="time"><?php echo $message->getMessageDate
>>> (); ?></td>
>>> </tr>
>>> <?php endforeach; ?>
>>> </tbody>
>>>
>>> For Ajax, everything is fine now. We'll get the <tbody> content. But
>>> for output type "html", the result will be this:
>>> <html>
>>> <head><title>logs!</title></head>
>>> <body>
>>> <tbody>
>>> <tr>
>>> <td class="name">John McClane</td>
>>> <td class="message">Yippie-kay-yay motherfucker</td>
>>> <td class="time">03:27</td>
>>> </tr>
>>> </tbody>
>>> </body>
>>> </html>
>>>
>>> What we need now is insert the wrapper IN BETWEEN "decorator" and
>>> "content" layer.
>>>
>>> Remember that the decorator template expects to output $slots
>>> ['content']. Hence, we actually have to modify the "content"
>>> layer to
>>> display the wrapper template (LiveSuccess.wrapper.php), and then
>>> prepend another "inner" layer (LiveSuccess.php) to the layer
>>> list. We
>>> do it like this, in the view:
>>>
>>> public function executeHtml(AgaviRequestDataHolder $rd)
>>> {
>>> // remember: first, you should have a base view and call a
>>> method on
>>> the parent to load the layout instead of doing it here.
>>> // second, loadLayout() would be enough since "standard" is
>>> the
>>> default layer
>>> $this->loadLayout('standard');
>>>
>>> // we get the "content" layer and change the template to
>>> the wrapper
>>> $c = $this->getLayer('content');
>>> $c->setTemplate('LiveSuccess.wrapper');
>>>
>>> // and then prepend the actual "inner" content template to
>>> the list
>>> $i = $this->prependLayer($this->createLayer
>>> ('AgaviFileTemplateLayer', 'inner'));
>>> $i->setTemplate('LiveSuccess');
>>> }
>>>
>>> And that's it! Now we have the desired result:
>>> <html>
>>> <head><title>logs!</title></head>
>>> <body>
>>> <div id="roomTitle"><?php echo $t['topic']; ?></div>
>>> <table border="0" cellspacing="0" cellpadding="0">
>>> <tbody>
>>> <tr>
>>> <td class="name">John McClane</td>
>>> <td class="message">Yippie-kay-yay motherfucker</td>
>>> <td class="time">03:27</td>
>>> </tr>
>>> </tbody>
>>> </table>
>>> </body>
>>> </html>
>>>
>>>
>>> IMPORTANT: Some advice regarding base views. In the original
>>> email, I
>>> recommended that you always have a base view you extend from where
>>> execute() throws an exception. This view would also have base
>>> methods
>>> you can call that load layers, maybe set dynamic slots, or do stuff
>>> like:
>>> $this->setAttribute('_contentType', $this->container-
>>> >getOutputType()-
>>>> getParameter('Content-Type'));
>>>
>>> However, there is a problem here. The whole point of having
>>> execute()
>>> throw an exception is that if there is a request using, say, ajax,
>>> that sets the output type to, say, "json" because of a routing rule
>>> like this:
>>> <route pattern="^XMLHttpRequest$" source="_SERVER
>>> [HTTP_X_REQUESTED_WITH]" stop="false" output_type="json" />
>>>
>>> And you then implement a base executeJson() in the base view... all
>>> of your views DO serve the json output type, and the normal
>>> execute()
>>> is never called, not even for actions/views that don't implement
>>> ajax
>>> features and should thus get an exception!
>>>
>>> To solve that problem, name these base methods differently. I
>>> suggest
>>> you call them "setupHtml", "setupJson" and so on, and then call them
>>> using $this->setupHtml($rd); etc inside your concrete view's
>>> executeHtml() method.
>>>
>>> Again, if there are any questions, let me know.
>>>
>>> Cheers,
>>>
>>> David
>>>
>>> _______________________________________________
>>> users mailing list
>>> [email protected]
>>> http://lists.agavi.org/mailman/listinfo/users
>>>
>>
>>
>> _______________________________________________
>> Agavi Dev Mailing List
>> [email protected]
>> http://lists.agavi.org/mailman/listinfo/dev
>>
>
> _______________________________________________
> Agavi Dev Mailing List
> [email protected]
> http://lists.agavi.org/mailman/listinfo/dev
>
_______________________________________________
Agavi Dev Mailing List
[email protected]
http://lists.agavi.org/mailman/listinfo/dev