node_build attempts to be helpful by copying all $node->content down to the $page structure. Thus, it copies the 'comments' element and the 'links' element by default. But those copies are not used at all. Instead, template_preprocess_node() works off of #node->content['comments'] and #node->content['links'] instead.
This patch removes the misleading copy.
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | drupal-recursive-error-when-rebuilding-node-build-564632-12.patch | 855 bytes | alan d. |
| #7 | nb2.diff | 12.29 KB | moshe weitzman |
| #5 | nb2.diff | 11.26 KB | moshe weitzman |
| #3 | nb2.diff | 8.25 KB | moshe weitzman |
| node_build.diff | 427 bytes | moshe weitzman |
Comments
Comment #1
Scott Reynolds commentedJust filed a related issue #564642: Preserve $node->content and $comment->content across multiple node views. I do not believe they are the same but relatively close.
Comment #2
yched commentedRemoving this looks fine by me, but then we should also remove the equivalents in comment_build(), user_view() (heh, who's inconsistently named ? surprise...)
Comment #3
moshe weitzman commentedUnlike the first patch here, I am now keeping the render array in $page structure and removing it from #node, #account, and #comment. This is more accessible during hook_page_alter(). This required a tiny bit of added code in the preprocess functions.
yched inspired me to do some cleanup. user_view() is now gone, in favor of a new user_build(). node_build(), user_build(), and comment_build() all work the same. They call the node_build_content(), user_build_content(), and comment_build_content() respectively. Those functions populate a $content element and instead of returning something, they just change their object by reference.
Comment #5
moshe weitzman commentedAttached patch fixes tests and adds a couple comments.
I ended up removing code which never took effect that changes the page title to My account instead of USERNAME when a user views own profile page. I had fixed a bug so that this code actually worked and then some tests started failing because they expected USERNAME. I think it is best to be consistent for all profile views.
Comment #7
moshe weitzman commentedFix tests
Comment #8
chx commentedThat's awesome!
Comment #9
webchickLooks like sensible clean-up. I like that the comment/user/node build functions are all harmonized now.
I had questions about the changes to user_page_title(), but it appears that we're overriding those in user_view() anyway, since on d.o, the title of http://drupal.org/user/24967 is not "My account" but "webchick". So this appears to be old cruft that doesn't apply anymore.
I asked Moshe to give the hook_page_alter() docs a spot-check and he said there was nothing that needed updating.
Committed to HEAD.
Comment #11
alan d. commentedNearly 3 years on, a small issue has arisen from this patch.
Steps to replicate are difficult, it requires a recursive rendering of the same entity. I discovered this when using an insert view filter that rendered the node that contained the filter was being rendered.
In a nut-shell:
Render a node.
Embed the same node somewhere within the build process.
This internal rebuilding results in "unset($node->content);"
Since it is an object, this also unsets the parent node's content array.
So at the end of field_attach_view() in the main node, you get "Fatal error: Unsupported operand types in modules/node/node.module on line 1362"
While normally I would just consider this as a idiots mistake, recursive looping is becoming more common.
IE: Another hypothetical examples:
Product has sub-products entity references and displays these. The sub-products hook into the field system decide to render the reverse relationship.
My first thoughts are that we shouldn't unset this and that we should reuse the content as required (memory overhead may be high). However, different view modes means that this is unsafe. So a bigger refactoring would be required to store the content along with the view mode.
Something like this ever so simplified pseudocode:
Back to the actual error, one work-around is:
And similar solution for user_build()
Comment #12
alan d. commentedThis reworks the workaround in #11 slightly.
Comment #13
alan d. commentedMoved to #564642: Preserve $node->content and $comment->content across multiple node views