The sequence of helper callbacks

Published on and tagged with cakephp  helper

While experimenting with the helper callbacks I noticed something I didn’t expect.

Have a look at the following helper implementing the callback methods:

class ExampleHelper extends AppHelper {
    public function beforeLayout() {
        echo 'beforeLayout';
    }

    public function afterLayout() {
        echo 'afterLayout';
    }
	
    public function beforeRender() {
        echo 'beforeRender';
    }
	
    public function afterRender() {
        echo 'afterRender';
    }
}

What will be the output if you have a simple view and you add this helper to the $helpers array of the respective controller?

Personally I would have expected an output like:

beforeLayout
<html>...
beforeRender
the content of the view
afterRender
...</html>
afterLayout

But to my surprise the output is quite different:

beforeRender
beforeLayout
afterLayout
<html>...
the content of the view
afterRender
...</html>

I’m not sure whether this output is generated due to bugs in the rendering process or because it is the intended output…

37 comments baked

  • truster

    Hi Daniel, I very appreciate your blog (no sarcasm). Thanks for pointing this thing out!
    Let me assure you that trac.cakephp.org/newticket is working and cakephp code is still just bunch of plaintext php files.

  • truster

    Anyway, it seems logical to me that output buffer is not started before beforeRender() and is not flushed before afterRender() callback. And for layout rendering is used View::$output property you can easily access from helper’s afterLayout().

  • rafaelbandeira3

    I don’t think it’s a bug, it’s more like an enhancement, as truster already explained the reasons why it would happen. But I would prefer it to be the way you prefer too.

  • Adam

    Errr… just because it’s echo()’d out of sequence doesn’t mean it’s *executed* out of sequence. Change those echo()’s to a $this->log() and you’ll find the execution order is a bit more logical.

    2008-10-23 21:58:35 Error: beforeRender
    2008-10-23 21:58:35 Error: view
    2008-10-23 21:58:35 Error: afterRender
    2008-10-23 21:58:35 Error: beforeLayout
    2008-10-23 21:58:35 Error: layout
    2008-10-23 21:58:35 Error: afterLayout

  • nate

    Wow…. you really are just completely, utterly clueless on how two-step rendering is supposed to work. Please refrain from posting such uneducated drivel until you do a little research.

  • Joel Perras

    Two-pass rendering, Daniel.

  • Joel Perras

    Whoops, didn’t mean to just repeat what nate said. Sorry.

  • Torsten Müller

    nate… come on. Daniel writes lots of good stuff. So if he misses the mark once in a while, I don’t think your harsh words are appropriate.

  • brian

    I have read Daniel for a while, and, I have to say, I agree with Nate’s assessment, way to quick to pull the trigger on stuff with little thought, investigation, or testing.

    It’s a blog, it’s his, and it is his choice, but don’t call it ‘cakebaker’ as I don’t that term applies any more, call it

    I_try_stuff_in_cakephp_and_write_my_opinions_with_little_forethought.42dh.com

  • Brendon Kozlowski

    Pretty hard criticisms from what I felt were just merely open ended questions posed to everyone.

    I do feel Daniel’s last sentence may have been poorly stated, however; which may have caused the backlash. I would say that I expected something more similar to the actual result than the “expected” behavior as Daniel reported, but if I thought about it a bit more, I probably would have come up with the same thing as the actual behavior. Regardless, I still had never heard of two-pass or two-step rendering. Does that make me clueless too? Hardly…

  • nate

    Sorry guys, I guess I just have high standards for what sort of things I feel should be released on the unsuspecting public. Once upon a time, this blog met those standards. These days… not so much. If you want to post a bunch of open-ended questions, that’s fine, but this wasn’t it.

    To me, a good open-ended question would be “what are the advantages and drawbacks of a two-step-rendered view?”, not “why doesn’t this work as I expect it to?”. Here, Daniel makes no effort to discover what or why of the system as it exists, and offers no real information, helpful or otherwise.

    @Brendon Kozlowski: That’s a perfectly fair point, and I certainly wouldn’t consider you clueless for not having heard of two-step rendering (everyone hears of things the first time at some point). But then, you’re not writing about it, and certainly not in a public forum where people expect to be imparted something of value (i.e. information) in exchange for their time spent reading. My specific criticism is regarding the lack of even a cursory attempt to understand why something is the way it is before writing about it.

    IMO, this type of blog posting is nothing but laziness and ineptitude.

  • Daniel Salazar

    Even in being “wrong”, this post sparked the conversation regarding two-pass rendering which I’d never heard of. So I do think it served its purpose and everyone learned a bit more about Cake.

    I appreciate your contributions Daniel. I’ve learned a lot from your posts. Keep on doing what you do…

  • Jonathan Snook

    @nate: lazy maybe, ineptitude no. But lazy in the sense that he didn’t ask anybody on the core team (which is what I would do :) ). Although, considering you guys read this blog, in a way, he did ask. Also, there’s no guidelines on what he’s allowed to post on his blog.

    So, why not just answer the question in a straightforward fashion so that those that come across the blog understand what it means. Even mentioning two-pass to two-step rendering doesn’t necessarily answer the question. The best I could uncover is the Styled View which didn’t really seem exactly the same.

    In this case, it just seems that a two step render means that the view gets rendered and then the layout gets rendered. That’s fine and seems obvious. But, this doesn’t explain why the afterRender happens inside the output buffering. Why not do it after the ob_get_clean? This would have all of the before/after calls executed outside the scope of output buffering. Again, this isn’t explained.

    Sure we can read the code line by line and we can understand two-pass rendering but it still doesn’t explain everything.

  • Pixelaté

    @nate: I love CakePHP but I seriously hate your direct involvement in the community – headed up by your narcissistic attitude.

    I’d prefer to read 100 pages of “uneducated drivel” rather than read your self-righteous, big-headed, crap.

    There are a million ways you can approach criticism and you always choose the most aggressive and ugly way.

    At least your consistent. Daniel has only on occasion posted “uneducated drivel”, you always post “self-righteous, big-headed, crap”.

    Have a nice day.

  • foobar

    Nice Pixelaté, i absolutly agree! ;)

  • rafaelbandeira3

    I can asure that Daniel knows about the whole “two-step rendering”, and everyone that folloes him on twitter can confirm as he had already twittered about it… futhermore, from where did you all took the idea that this post was talking about the way cake render views? I re-read the post, and I just couldn’t see from where this idea was taken…

    criticism is one thing, talking shit just to talk is another completely different. Nate is agressive and rude, always, and we all know, we’re all fine with this, Daniel likes to question everything and share his thoughts and concepts about things he notice or he deals with, and we all should be fine with this too, so @brian, if you got nothing to add, get your mouth shut and do something worth with your time. I don’t think it’s a good practice nowadays to have your name associated with crappy comments on the web…

    @cakebaker: you might have noticed that the ticket was set to “Enhancement”, I really think that beforeRender and afterRender, beforeLayout and afterLayout, callbacks could be usefull to output something, and the ticket is quite handy in my opinion – but as an enhancement.

    I’m not about “defend” or “attack” someone… I only think that as Daniel can write unliked stuff, commenters can answer in unliked ways, in their own styles. But please, append your comment only if it really has something to add to the thread.

  • Joel Perras

    For everyone who is confused about what a ‘two step/phase’ render is, I recommend the quasi-seminal “Patterns of Enterprise Application Architecture” by Martin Fowler:

    http://www.amazon.com/exec/obidos/ASIN/0321127420

    If you want to understand/implement/create web frameworks, this is the place to start. The two-pass rendering technique is discussed under ‘web presentation patterns’.

  • truster

    @cakebaker: can I take my 1st comment in this thread back? I do not want to be considered I am behaving the same, like nate, CakePHP Lead Developer.

  • Henrik

    I must admit Nate u are getting more and more irretating… I am seriously thinking about dropping cake as a result of your idiotic behavior there should be room for everyone here.. And ITS A FUCKING BLOG

  • Xr

    While we’re bashing each other, here’s my insight on the issue:

    – No, the current behavior is not intuitive. It might be a good idea and/or have perfectly good reasons to be that way, but it’s not intuitive.

    – Yes, the Cake devs sometimes behave like they are on 4chan or something.

    – Saying you will drop Cake because the *some* of the devs are *sometimes* misbehaving is like saying you stopped using anything from the FSF because Stallman could act in a remake of One Flew Over the Cuckoo’s Nest. It’s irrelevant as long as it doesn’t seriously impact the quality of the software.

  • Henrik

    Its er personal view… I dont want to support some software where the devs think they are gods of some sort.!

  • Nightwish

    @nate: I know, it’s so obvious there’s no point in documenting it, that’s the CakePHP way! I’m somewhat sad to have figured it out only when I am already stuck with it.

  • brian

    Let me take this moment to formally apologize to Daniel, and to all of you. I did exactly what I accused Daniel of doing, so I went back to re-read about 20 of his recent posts. They were all helpful in a variety of ways, and, wow, Nate is often like a bulldog on the attack. Whatever happened between you guys in the past, if something did happen, I hope you can let it go.

    I have always found the cakephp community civil and helpful, and this thread of comments does disturb me a bit.

    And, as recommended to me by @rafaelbandeira3, I will comment when I can add value. Otherwise, I will read and learn. Not to get philosophical, but we don’t need more fighting and wars of any kind in our world, I hope we can put aside personalities and create great software.

  • Frank

    Xr said:
    >Saying you will drop Cake because the *some* of the devs are *sometimes* misbehaving […]
    >It’s irrelevant as long as it doesn’t seriously impact the quality of the software.

    I believe that there is more than just quality of product to an open source project. It’s about the community that’s being brought together , contribute and consider things a core team of whatever size would never have gotten to.

    And this is where Nate has been a most disturbing factor since I got into Cake in late 2006. I have seen many occurences where people asked questions that do not meet up to his expected level of self education. And bang boom bash they get some words from him that make sure they will never feel like asking anything again. And the worst is: he even does this when he does not have the necessary expertise, as can be seen @google groups in a recent GPL/MIT license discussion.

    My honest hope is that having someone with such a volatile personality on the core team will not result in problems for the project someday.

  • cakebaker

    @all: Thanks for your comments!

    As pointed out by Adam my assumption that the echoed sequence is identical with the sequence the code is executed is *wrong*. My bad. I should have checked this, and I’m sorry about this mistake. A title like “The output sequence of helper callbacks” would have been more correct than “The sequence of helper callbacks”.

    @truster: Thanks for the tip, in the meantime I opened a ticket for it: ticket #5650.

    @nate: Yes, I made a mistake as I explained above. Only, it doesn’t change what I noticed, the message is still the same: the output is not what I expected. And knowing you are using “two-step rendering” in the implementation doesn’t make the output look more right to me. You are developing a framework, and if you provide some callbacks in a view-related concept like a helper you can’t assume nobody wants to use those callbacks to output some stuff. And you can’t assume framework users will know anything about “two-step rendering”.

    @Brendon: The reason for my last sentence was that on the one hand I thought it’s a bug but on the other hand it seemed unlikely to have two things going wrong with the callbacks…

    @nate: I described a behavior I didn’t expect. Nothing more. Nothing less. If that’s below your “high standards”, well, I can live with that, and I’m sorry I have wasted your time.

    @Daniel: You are welcome :)

    @Jonathan: I think what is meant with “two-step rendering” is the “Two step view” pattern. From “Patterns of Enterprise Application Architecture”:

    “The key to this pattern is in making the transformation to HTML a two-stage process. The first stage assembles the information in a logical screen structure that is suggestive of the display elements yet contains no HTML. The second stage takes that presentation-oriented structure and renders it into HTML.”

    But it is a pattern, and a pattern can be implemented in different ways. Knowing this pattern is used doesn’t explain why the output is like it is.

    @Rafael: Yes, I have seen that the ticket was changed. Makes sense.

    @Joel: Thanks for the book link! And yes, it is a good book about patterns.

    @truster: I have no problem with your first comment, you made a valid point ;-)

    @Henrik: I wouldn’t abandon a framework just because of some people who are “strange”. As long as it allows you to get your job done, use it. In the end it’s not really important by whom it is developed.

    @brian: Apology accepted :) (I didn’t take your comment personally, and there is also something to learn for me from such comments)

    There were differences in the past and it seems Nate and I just don’t get along very well due to our personalities and our different views on software engineering.

    But all in all the cakephp community is usually civil and helpful. The exception proves the rule.

  • nate

    My apologies if my attitude offends anyone (other than Daniel). It is simply my direct response to his behavior and personality.

    Daniel has been using CakePHP for years. He knows that views are rendered before layouts. Daniel is a logical person, therefore it follows that (based on the preceding) he would reasonably infer why the callbacks are fired in the order they are, even if that order would “appear” not to be consistent with the order of content as it is laid out on the page.

    For him to suggest that he is somehow “confused” by this is disingenuous and misleading. Furthermore, were he legitimately confused, he still has the ability to examine the code and draw some reasonable conclusions, rather than posing idle “questions” about the code quality.

    For as bad as you people think my attitude is, Daniel’s is far worse, and far more destructive. Even more so for the fact that he masks it by feigning confusion and “asking questions,” but his intent is eminently clear. Since being removed from the core team, Daniel has consistently posed “questions” about CakePHP aimed at criticizing design decisions (often based entirely on straw-man arguments, as above) and undermining confidence in the framework as a whole.

    Don’t get me wrong, I’m all for healthy debate. It’s the only reason Cake is as great as it is. What Daniel is engaging in, however, are simply unqualified, unfounded attacks, with no genuine intent or desire to improve things.

    What little value he has added to the CakePHP community is negated by orders of magnitude as a result of his negative, critical, uselessly pedantic behavior.

    You people can think what you want, but at the end of the day, I build things up, Daniel tears them down. If his campaign of useless criticism causes me to loose my cool every now and again, well, I’m willing to cut myself a little slack.

    CakePHP is an Open Source project. I can’t build a fence around and yell “mine! you get out!”, nor am I going to try. But if someone within the community is actively working to stir up dissent (the bad kind), you can certainly bet that I am going to respond to it. I have precious little tolerance for such people.

  • rafaelbandeira3

    @cakebaker: “The exception proves the rule.” – Nice, very nice indeed…

    @nate: that makes a lot of sense, really. If every now and then everyone could join in a debate, aguing as it wants and doing as it cares about, we can always have great results. You pointed out your points, very nice… I agree with some points, really do. But I don’t think Daniel does it in a predicted way, as a part of a masterplan to blow things up on cake’s universe. I’ve seen you complimenting him in some posts, as he does, and we all know he does, a good job documenting things. I must say, this last comment worths.

  • Optimising php-faker to be 10x faster! : Adam Royle

    […] a link trail following the sequence of helper callbacks debacle yesterday, I stumbled across an interesting php library for generating random data – php-faker, […]

  • cakebaker

    @nate: Calm down and start listening!

    It is up to you whether you see this article, and everything else I write, as useless crap of someone who has no clue about anything, or whether you see it as feedback from which you could learn something to improve the framework. It’s your choice.

    Oh, and please stop to attack me on the personal level. This is an article about the output of a piece of software, so keep it on the technical level. And if you don’t have to say anything on that level, then please shut up. Thanks.

  • The Mullet

    well… nate does have a point here: if you follow the tickets @caketrac closely, you’ll see that daniel really does not provide much help but rather often opens tickets which simply seem to have one goal only: question the way certain things are done, simply because they don’t work the way he expects them to work (dho is his username if you wish to search for some facts).

    Still, nate, I believe that your comment here is the bigger problem. If daniel really is the uneducated moron you believe him to be, why do you follow his blog at all? To keep his disciples from following him? Gosh, if I’d be trying to discuss (or even just insult through a short comment) everything I don’t agree on with everyone that I consider being an uneducated driveller, I’d be doing nothing else than that. Instead, I simply remove such blogs from my feed reader.

    That will not happen to daniels blog, though. I do highly regard his writings, which are much better than the tickets he submits at trac.

  • cakebaker

    @The Mullet: Thanks for your comment!

    Here the link to the tickets I opened.

    Do you have some examples of tickets which could have been more helpful?

  • Felix Geisendörfer

    Daniel: I have a single question for you: Do you still enjoy programming and working with CakePHP?

  • The Mullet

    Daniel… this is not a court case where anyone has to prove anything. But being a frequent reader of tickets at cake-trac, my impression is that you are the person who submits the most number of tickets which simply describe unexpected behavior, alas things that can be done this or that way, but haven’t been done the way you expect.

    Besides, many people know about the history you share with the core team. So please do not make the same mistake by alienating people by questioning their motives – just like nate did. I am not on one side or the other. I enjoy your blog, but I do often dislike your tickets. Just like I appreciate nate’s work, but I do not like the way he comments other people’s contributions.

  • Abhimanyu Grover

    I appreciate your posts always Daniel. I think its perfectly logical to raise a question like this. And as always, it has been increasing my CakePHP knowledge from years – just like it did in this post.

  • cakebaker

    @Felix: Difficult question. I think “enjoy” is the wrong word. For me, CakePHP is a tool, like a hammer for a carpenter. A carpenter enjoys to build some furniture, and I enjoy to build web applications. And to do that, I use CakePHP as my preferred tool. Sometimes I love it, sometimes I hate it.

    @The Mullet: Hm, maybe I have to describe better why something should be done in a different way?

    @Abhimanyu: You are welcome :)

  • Nicolas F

    CakePHP is a great framework – The Bakery and this blog contribute a lot to its learning curve. Latly more questions have been raised here targeting the concept of how “new/existing features” are implemented, which I appreciate. But I wonder what kind of impressions someone new to this framework would have if he only focuses on this blog’s last posts?

    However, this is a personal blog and not the official CakePHP Blog. So keep on posting / baking Daniel.

  • cakebaker

    @Nicolas: Thanks for your comment!

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License