Johan,
both issues are now fixed in SVN. Again, thanks for the report.
David
Am 30.01.2007 um 16:16 schrieb David Zülke:
> 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
>
_______________________________________________
Agavi Dev Mailing List
[email protected]
http://lists.agavi.org/mailman/listinfo/dev